gpt4 book ai didi

ios - NSFetchedResultsController 并不总是调用 didChangeObject :atIndexPath:forChangeType:newIndexPath: for NSFetchedResultsChangeMove

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:04:06 25 4
gpt4 key购买 nike

我在请求中使用 NSFetchedResultsControllersortDescriptors 来填充包含大量结果的表。我注意到,当发生将行从表底部附近移动到顶部的更改时,根本不会调用 didChangeObject:atIndexPath:forChangeType:newIndexPath:

奇怪的是,我可以通过遍历所有获取的对象并在调用 performFetch 后立即访问它们的任何属性来解决这个问题。

关于问题可能是什么的任何提示,或者这只是一个模糊的 Apple 错误?

这是我的代码:

NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
request.entity = [NSEntityDescription entityForName:@"MyObject" inManagedObjectContext:context];
request.sortDescriptors = @[NSSortDescriptor sortDescriptorWithKey:@"order" ascending:NO]];
request.fetchBatchSize = 20;
NSFetchedResultsController *fetched = [[NSFetchedResultsController alloc]
initWithFetchRequest:request
managedObjectContext:context
sectionNameKeyPath:nil
cacheName:nil];
fetched.delegate = self;
NSError *error = nil;
if (![fetched performFetch:&error]) {
NSLog(@"Unresolved error fetching objects: %@", error);
}

// Should not be necessary, but objects near the bottom won't move to the top without it.
for (MyObject *o in fetched.fetchedObjects) {
o.someAttribute;
}

2014 年 9 月 12 日更新:

我将所有数据保存在后台托管对象上下文中,这似乎与我所看到的问题有关。这是我将更改合并到主对象上下文的代码:

+(void)initSaveListener {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mergeChanges:)
name:NSManagedObjectContextDidSaveNotification
object:[self privateContext]];
}

+(void)mergeChanges:(NSNotification*)notification {
NSManagedObjectContext *context = [self mainContext];

[context performBlock:^{
[context mergeChangesFromContextDidSaveNotification:notification];
NSError *error = nil;
if (![context save:&error]) {
NSLog(@"error merging changes %@, %@", error, [error userInfo]);
}
}];
}

最佳答案

事实证明,这个问题是由于对 managedObjectContext 的更改是从另一个使用 NSManagedObjectContextDidSaveNotification 的上下文传播的。这篇博文详细解释了为什么这会导致 NSFetchedResultsController 出现问题,以及如何修复它:

http://www.mlsite.net/blog/?p=518

这是我上面代码上下文中的具体修复:

+(void)mergeChanges:(NSNotification*)notification {
NSManagedObjectContext *context = [self mainContext];

// Fault all objects that have changed so that NSFetchedResultsController will see the changes.
NSArray *objects = [[notification userInfo] objectForKey:NSUpdatedObjectsKey];
for (NSManagedObject *object in objects) {
[[context objectWithID:[object objectID]] willAccessValueForKey:nil];
}

[context performBlock:^{
[context mergeChangesFromContextDidSaveNotification:notification];
NSError *error = nil;
if (![context save:&error]) {
NSLog(@"error merging changes %@, %@", error, [error userInfo]);
}
}];
}

关于ios - NSFetchedResultsController 并不总是调用 didChangeObject :atIndexPath:forChangeType:newIndexPath: for NSFetchedResultsChangeMove,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25588624/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com