Ste*_*ani 3 core-data objective-c nsfetchedresultscontroller
我正在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
Run Code Online (Sandbox Code Playgroud)
而在重装它viewWillAppear与[self.tableView reloadData]
简化 Person
@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
Run Code Online (Sandbox Code Playgroud)
我的数据是通过网络请求生成的,用于获取一堆json并将其转换为NSManagedObjects.排序看起来很好.
1 Person A time 1437498898
2 Person B time 1437498897
3 Person C time 1437498896
Run Code Online (Sandbox Code Playgroud)
当我使用方法调整sortDate属性时,在我得到一个更改类型,列表的排序方式如下:Person C-viewed<NSFetchedResultsControllerDelegate>NSFetchedResultsChangeMove
1 Person C time 1437498900
2 Person A time 1437498898
3 Person B time 1437498897
Run Code Online (Sandbox Code Playgroud)
当我尝试为Person B我做同样的事情而不是获得更改类型时NSFetchedResultsChangeUpdate,列表的排序方式如下:
1 Person C time 1437498900
2 Person A time 1437498898
3 Person B time 1437498905
Run Code Online (Sandbox Code Playgroud)
我可以不断更新sortDate的人员A和C他们会继续正确排序.任何更改Person B都不会显示,直到应用程序重新启动后,然后Person B停止更新.删除并重新安装我的应用程序(清除CoreData)没有帮助.
如果我把一个print在命令- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath那么我可以看到Person B的sortDate确实已经更新到新的价值,这应该引起NSFRC创建一个Move事件,而不是Update改变类型.
// 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
Run Code Online (Sandbox Code Playgroud)
那么,为什么NSFetchedResultsController回归错了NSFetchedResultsChangeType呢?
来自以下文件NSFetchedResultsControllerDelegate:
当对象上的已更改属性是获取请求中使用的排序描述符之一时,将报告移动.
在这种情况下,假定更新了对象,但没有向委托发送单独的更新消息.
当对象的状态更改时,将报告更新,但更改的属性不是排序键的一部分.
我希望这能说清楚为什么你的回调中会有不同的更改类型.考虑到这一点,我建议清理你提取的结果控制器并委托回调:
"sortDate".deleteRowsAtIndexPaths并insertRowsAtIndexPaths适当.最后的想法:您为一个特定对象描述的不稳定行为(而其他对象似乎按预期工作)指向其他可能的错误,例如与更新sortDate属性有关.
此外,您没有keypath在获取的结果控制器中解释该变量.也许分组对您正在观察的行为有所贡献.
最后,您可能是此处描述的获取结果控制器委托的罕见故障的受害者(包括变通方法).- 此外,不要忘记,如果您不需要为更改设置动画,则可以始终只使FRC无效并进行呼叫reloadData.
如果没有什么帮助我会重构,NSDate而不是NSNumber更直观.
| 归档时间: |
|
| 查看次数: |
438 次 |
| 最近记录: |