Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c NSFetchedResultsController返回错误的NSFetchedResultsChangeType_Objective C_Core Data_Nsfetchedresultscontroller - Fatal编程技术网

Objective c NSFetchedResultsController返回错误的NSFetchedResultsChangeType

Objective c NSFetchedResultsController返回错误的NSFetchedResultsChangeType,objective-c,core-data,nsfetchedresultscontroller,Objective C,Core Data,Nsfetchedresultscontroller,我正在创建一个NSFetchedResultsController,在viewDidLoad NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:NSStringFromClass([Person class])]; fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:NSStringFromSelector

我正在创建一个
NSFetchedResultsController
,在
viewDidLoad

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:NSStringFromClass([Person class])];
fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:NSStringFromSelector(@selector(sortDate))
                                                               ascending:NO]];

NSFetchedResultsController *controller = [[NSFetchedResultsController alloc] initWithFetchRequest:request
                                                                             managedObjectContext:self.mainManagedObjectContext
                                                                               sectionNameKeyPath:nil
                                                                                        cacheName:nil];
controller.delegate = delegate;
NSError *error;
if (![controller performFetch:&error]) {
    NSLogError(error);
}

// Connecting up all the delegates for UITableView
然后在
视图中重新加载它将与
[self.tableView reloadData]

简化的

@interface Person : NSManagedObject
/// an NSTimeInterval representing the Unix Epoch
@property (nonatomic, retain) NSNumber *sortDate;
- (void)viewed;
@end

@implementation Person
// nothing fancy or custom - no extra KVO or primitive assignments
@dynamic sortDate;
- (void)viewed {
    self.sortDate = @([NSDate date].timeIntervalSince1970);
}
@end
我的数据是通过网络请求生成的,以获取一组json并将其转换为
NSManagedObject
s。排序看起来不错

1 Person A time 1437498898
2 Person B time 1437498897
3 Person C time 1437498896
当我使用
-viewd
方法调整
Person C
上的
sortDate
属性时,在
中,我得到一个更改类型
NSFetchedResultsChangeMove
,列表排序如下:

1 Person C time 1437498900
2 Person A time 1437498898
3 Person B time 1437498897
1 Person C time 1437498900
2 Person A time 1437498898
3 Person B time 1437498905
当我尝试对
人员B
执行相同操作时,我得到的更改类型是
NSFetchedResultsChangeUpdate
,列表排序如下:

1 Person C time 1437498900
2 Person A time 1437498898
3 Person B time 1437498897
1 Person C time 1437498900
2 Person A time 1437498898
3 Person B time 1437498905
我可以持续更新个人
A
C
sortDate
,他们将继续正确排序。对
Person B
的任何更改只有在应用程序重新启动后才会显示,但
Person B
停止更新。删除并重新安装我的应用程序(以清除CoreData)没有帮助

如果我将
print
命令放在
-(void)控制器:(nsfetchedresultscoontroller*)控制器didChangeObject:(id)一个对象atIndexPath:(nsindepath*)indexath for changeType:(NSFetchedResultsChangeType)type newindexath:(nsindepath*))newIndexPath
然后我可以看到
人员B
sortDate
确实已更新为新值,这将导致NSFRC创建
移动
事件,而不是
更新
更改类型

// Original Sort (logs from cellForRowAtIndexPath)
Time 1437506506 - Person B
Time 1437506490 - Person C
Time 1437506381 - Person D
Time 1437506128 - Person A

// Change Person A
Updating SortDate 1437506128 -->  1437506599
Time 1437506599 - Person A for NSFetchedResultsChangeMove

// Sorted Correctly
Time 1437506599 - Person A
Time 1437506506 - Person B
Time 1437506490 - Person C
Time 1437506381 - Person D

// Change Person B
Updating SortDate 1437506506 -->  1437506610
Time 1437506610 - Person B for NSFetchedResultsChangeUpdate

// Sorted Incorrectly
Time 1437506599 - Person A
Time 1437506610 - Person B
Time 1437506490 - Person C
Time 1437506381 - Person D

那么,为什么
NSFetchedResultsController
返回了错误的
NSFetchedResultsChangeType

来自
NSFetchedResultsController委托的文档:

当对象上已更改的属性是fetch请求中使用的排序描述符之一时,将报告移动

在这种情况下,假定对象更新,但不向委托发送单独的更新消息

当对象的状态发生更改时,会报告更新,但更改的属性不是排序键的一部分

我希望这能清楚地解释为什么您在回调中得到不同的更改类型。考虑到这一点,我建议清理获取的结果控制器和委托回调:

  • 消除FRC中的冗余谓词
  • 使用与属性名称相对应的排序键:
    “sortDate”
  • 确保委托回调方法将表视图单元格移动到新的索引路径,即根据需要调用
    deleteRowsAtIndexPaths
    insertRowsAtIndexPaths
最后一点思考:您为一个特定对象描述的不稳定行为(而其他对象似乎按预期工作)指向了其他可能的错误,例如与更新
sortDate
属性有关的错误

此外,您没有解释“获取结果”控制器中的
keypath
变量。也许分组对您观察到的行为有影响

最后,您可能是所描述的获取结果控制器委托(包括解决方法)的罕见故障的受害者另外,不要忘记,如果您不需要设置更改的动画,您总是可以使FRC无效并调用
reloadData


如果没有任何帮助,我将使用
NSDate
而不是
NSNumber
进行重构,这更直观。

代理回调不会收到带有
newindepath
移动
更改类型-它会收到
更新
更改类型文档引用中的最后一句话指向排序问题。-更新对象时查找错误。它们都调用相同的
viewsed
方法来执行此操作。为什么
sortDate
会是某些对象的排序键,而不是其他对象的排序键?我更新了答案。可能您是一个罕见故障的受害者。我删除了
didChangeObject
方法,并在
controllerDidChangeContent:
中执行了
[tableView reloadData]
,排序问题保持不变。