Objective c MagicalRecord&x2B;核心数据在上下文之间找不到对象,尽管objectID字符串比较工作正常
我有一个NSFetchedResultsController,可以查询核心数据实体“MyGalleryPhoto” 我试图删除一些对象,遇到了一些问题。我用的是MagicalRecord。这是我对代码的最初尝试,在我看来应该可以很好地工作。在代码运行时,对象肯定存在,因为它们显示在fetchedResultsController中Objective c MagicalRecord&x2B;核心数据在上下文之间找不到对象,尽管objectID字符串比较工作正常,objective-c,core-data,magicalrecord,Objective C,Core Data,Magicalrecord,我有一个NSFetchedResultsController,可以查询核心数据实体“MyGalleryPhoto” 我试图删除一些对象,遇到了一些问题。我用的是MagicalRecord。这是我对代码的最初尝试,在我看来应该可以很好地工作。在代码运行时,对象肯定存在,因为它们显示在fetchedResultsController中 [MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *localContext) {
[MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *localContext) {
for (MyGalleryPhoto *myGalleryPhoto in [self.fetchedResultsController.fetchedObjects objectsAtIndexes: self.selectedIndexes]) {
NSError *error = nil;
MyGalleryPhoto *localMyGalleryPhoto = (MyGalleryPhoto *) [localContext existingObjectWithID: myGalleryPhoto.objectID error: &error];
NSLog(@"error: %@:%@", [error localizedDescription], [error userInfo]);
NSLog(@"mygp: %@", [localMyGalleryPhoto description]);
[localMyGalleryPhoto deleteInContext: localContext];
}
} completion:^(void){
}];
此代码不起作用。找不到myGalleryPhoto条目,返回的错误是:“操作无法完成。(Cocoa错误133000。)”我还尝试使用MR_inContext,它只调用existingObjectWithId:error:
经过一番周折,我想出了这个邪恶的弗兰肯斯坦怪兽,它从实体中取出所有记录,并比较objectid的字符串表示。这个很好用。为什么?我现在使用的是我今天从GitHub下载的MagicalRecord的副本,最新的XCode,最新的SDK等等
[MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *localContext) {
NSArray *allMyGalleryPhotos = [MyGalleryPhoto findAllInContext: localContext];
for (MyGalleryPhoto *myGalleryPhoto in [self.fetchedResultsController.fetchedObjects objectsAtIndexes: self.selectedIndexes]) {
MyGalleryPhoto *myGalleryPhotoToDelete = nil;
for (MyGalleryPhoto *existingMyGalleryPhoto in allMyGalleryPhotos) {
NSString *existingURLString = [[existingMyGalleryPhoto.objectID URIRepresentation] absoluteString];
NSString *URLString = [[myGalleryPhoto.objectID URIRepresentation] absoluteString];
NSLog(@"ExistingURLString: %@", existingURLString);
NSLog(@"URLString: %@", URLString);
if ([URLString isEqualToString: existingURLString]) {
myGalleryPhotoToDelete = existingMyGalleryPhoto;
}
}
if (myGalleryPhotoToDelete) [myGalleryPhotoToDelete deleteInContext: localContext];
}
} completion:^(void){
}];
Cocoa错误13000是引用完整性错误,如中所述。这意味着您正在寻找商店中不存在的对象。在更实际的层面上,这意味着您的上下文(我假设您有多个托管对象上下文)不同步。也就是说,您已经向一个上下文添加了一个新对象,而另一个上下文没有该对象,因为之前的上下文尚未保存 关于您的代码,我在第一个示例中看到的第一个问题是,您在一开始就跨越了线程边界。fetchedResultsController在另一个上下文中有一个对对象的引用(我将假定为默认上下文)。每次调用saveInBackground时,它都会提供一个新的上下文供您使用,但它也会将该代码块放在后台线程上。跨越线程边界,即使是在新版本的核心数据中,也会让您在随机时间遇到疯狂、难以追踪的问题 如果您试图在第一个(更简单的)代码块中执行的操作的要点是您有一个要从应用程序中删除的照片对象集合。我会这样做:
NSPredicate *objectsToDelete = [NSPredicate predicateWithFormat:@"self in %@", self.fetchedResultsController.fetchedObjects];
[MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *)localContext
{
[MyGalleryPhoto deleteAllMatchingPredicate:objectsToDelete inContext:localContext];
}];
deleteAllMatchingPredicate方法应该在正确的上下文中查找对象(您在第一段代码中没有这样做),以便删除它们。它还将对象设置为错误加载,因此我们不会加载内存中的所有内容,只会立即删除它。它只加载所需的内容,不再加载
在这种情况下,我不会使用ID:为的existingObjectWithID。此方法从不加载故障。您的用例意味着它将把整个对象加载到内存中,但无论如何都会删除它