【问题标题】:Core Data moc reset causes fault on Lion, okay on Snow LeopardCore Data moc 重置导致 Lion 出现故障,Snow Leopard 上还可以
【发布时间】:2011-08-29 18:28:02
【问题描述】:

我有一个使用 Xcode 3.x 在 Snow Leopard 上开发的应用程序。它使用 Core Data 和一个名为 Parish 的实体。

它在 Snow Leopard 上运行良好。当我将我的 Macbook 升级到 Lion 时,该应用程序大部分工作正常,但现在在特定情况下崩溃:

我的应用允许用户导入数据。我为用户提供了在开始新导入之前删除当前核心数据存储中的所有数据的选项。

我实现了这样的数据删除:

[self.managedObjectContext reset]; //to drop pending changes
[self.managedObjectContext lock];

// Now delete all peristent stores in this context
NSArray *stores = [self.managedObjectContext.persistentStoreCoordinator persistentStores];

for (NSPersistentStore *store in stores)
    {
    [self.managedObjectContext.persistentStoreCoordinator removePersistentStore:store error:nil];
    [[NSFileManager defaultManager] removeItemAtPath:store.URL.path error:nil];
    } 

[self.managedObjectContext unlock];

这在 Snow Leopard 上运行良好,但在 Lion 上运行相同(未修改)的代码会在 [self.managedObjectContext reset]; 时导致此错误;调用:

2011-08-29 17:37:24.349 ParishFinderHelperV2[2549:707] An uncaught exception was raised
2011-08-29 17:37:24.349 ParishFinderHelperV2[2549:707] CoreData could not fulfill a fault for
'0x107a0f9a0 <x-coredata://11995B9B-24CB-447F-BC18-E1A9F530C70C/Parish/p28367>'
2011-08-29 17:37:24.359 ParishFinderHelperV2[2549:707] (
    0   CoreFoundation                      0x00007fff963f6986 __exceptionPreprocess + 198
    1   libobjc.A.dylib                     0x00007fff8c60dd5e objc_exception_throw + 43
    2   CoreData                            0x00007fff97c24934 _PFFaultHandlerLookupRow + 916
    3   CoreData                            0x00007fff97c24254 _PF_FulfillDeferredFault + 212
    4   CoreData                            0x00007fff97c240d8 _sharedIMPL_pvfk_core + 56
    5   CoreData                            0x00007fff97c5ad3e -[NSManagedObject valueForKey:] + 222
    6   Foundation                          0x00007fff8d8ebe12 -[NSFunctionExpression expressionValueWithObject:context:] + 821
    7   Foundation                          0x00007fff8d8eba54 -[NSComparisonPredicate evaluateWithObject:substitutionVariables:] + 206
    8   Foundation                          

我查看了 Apple 文档并在 Google 上搜索过,但不明白为什么会发生这种情况。

谁能建议我如何解决这个崩溃问题?

更新: 其中一位评论者(谢谢)建议手动删除商店中的所有记录。我已经使用以下代码实现了这一点,虽然考虑到我必须删除大量记录,但工作速度非常慢:

NSFetchRequest * fetch = [[[NSFetchRequest alloc] init] autorelease];
[fetch setEntity:[NSEntityDescription entityForName:@"Parish" inManagedObjectContext:context]];
NSArray * result = [context executeFetchRequest:fetch error:nil];

for (id parish in result)
    [context deleteObject:parish];

谁能建议一种在一次操作中删除所有记录(或商店本身)的方法?

谢谢

达伦。

【问题讨论】:

  • 我不认为在依赖于它的托管对象上下文打开时删除持久存储协调器是有效的行为。它可能对 Snow Leopard 有效,但我看不出它是如何有效的。你的用例是什么?
  • 当用户选择将新数据集导入应用程序时,他们可以添加到当前记录或替换核心数据存储中的所有内容。当他们想要替换所有内容时,我执行上面的代码。在 SL 上一切正常,但在 Lion 上却不行。你能提出一个更好的方法来实现这个结果吗?谢谢,达伦。
  • 为什么不删除所有现有对象以防用户想要替换所有内容?
  • 您应该在调用-reset 之前删除 managedObjectContext 中的所有对象。请参阅文档,它明确指出应删除接收者持有的任何引用,因为它们将失效。
  • 感谢所有回复。我在商店中有 15000 条记录,按顺序删除每条记录效率不高。有没有办法快速“清空”核心数据存储?谢谢,达伦。

标签: objective-c cocoa core-data


【解决方案1】:

这似乎运作良好,而且很快:

NSPersistentStoreCoordinator *psc = [self.managedObjectContext.persistentStoreCoordinator retain];
NSArray *stores = [psc persistentStores];

// Delete the context and the psc
[self.managedObjectContext release], self.managedObjectContext = nil;

// Now delete all peristent stores in this context
for (NSPersistentStore *store in stores)
{
    [psc removePersistentStore:store error:nil];
    [[NSFileManager defaultManager] removeItemAtPath:store.URL.path error:nil];
}

// Create the new stack now the old stack has been deleted
if (!(self.managedObjectContext = [[self createManagedObjectContext] retain]))
{
    NSAssert(NO, @"Cannot create the managedObjectContext");
    return (NO);
}

[psc release];

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-25
    • 1970-01-01
    • 1970-01-01
    • 2012-01-07
    • 1970-01-01
    • 1970-01-01
    • 2011-01-07
    相关资源
    最近更新 更多