【发布时间】:2011-12-20 18:58:53
【问题描述】:
我收到一个错误,似乎很明显是给已释放对象的消息,但我无法弄清楚我在哪里管理内存错误。这是我创建持久存储协调器的代码。它基于 Core Data 应用程序模板。我可能已经改变了一点,但我认为不会改变。
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}
/* Reminder: in Simulator this is in /Users/<username>/Library/Application Support/iPhone Simulator/User/Applications/<bundleid>/Documents/Wordfare.sqlite */
NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"Wordfare.sqlite"]];
NSError *error;
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error]) {
[persistentStoreCoordinator release];
persistentStoreCoordinator = nil;
}
return persistentStoreCoordinator;
}
当我从 addPersistentStore 收到错误时会出现问题,因为我更改了我的模型并且我试图打开一个使用以前的模型创建的商店。当然,一个答案是“不要那样做”。我不会,但我希望代码是健壮的。上面的代码运行没有任何问题,但是当我按下主页按钮时,应用程序崩溃并出现以下错误:
2011-11-02 16:39:53.751 Wordfare[11137:207] -[__NSCFArray tryLock]:无法识别的选择器发送到实例 0x5a122f0
2011-11-02 16:39:53.783 Wordfare[11137:207] * 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:'-[__NSCFArray tryLock]:无法识别的选择器发送到实例 0x5a122f0'
* 首次抛出时调用堆栈:
(
0 CoreFoundation 0x012ed5a9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x01441313 objc_exception_throw + 44
2 CoreFoundation 0x012ef0bb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x0125e966 转发 + 966
4 核心基础 0x0125e522 _CF_forwarding_prep_0 + 50
5 CoreData 0x010d9ef0 -[_NSSQLCoreConnectionObsever _purgeCaches:] + 112
6 基础 0x00370669 _nsnote_callback + 145
7 CoreFoundation 0x012c59f9 __CFXNotificationPost_old + 745
8 CoreFoundation 0x0124493a _CFXNotificationPostNotification + 186
9 基础 0x0036620e -[NSNotificationCenter postNotificationName:object:userInfo:] + 134
10 UIKit 0x0060aa0b -[UIApplication_handleApplicationSuspend:eventInfo:] + 554
11 UIKit 0x00614039 -[UIApplication handleEvent:withNewEvent:] + 4127
12 UIKit 0x0060babf -[UIApplication sendEvent:] + 71
13 UIKit 0x00610f2e _UIApplicationHandleEvent + 7576
14 图形服务 0x03851992 PurpleEventCallback + 1550
15 核心基础 0x012ce944 CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION + 52
16 CoreFoundation 0x0122ecf7 __CFRunLoopDoSource1 + 215
17 核心基础 0x0122bf83 __CFRunLoopRun + 979
18 CoreFoundation 0x0122b840 CFRunLoopRunSpecific + 208
19 CoreFoundation 0x0122b761 CFRunLoopRunInMode + 97
20 图形服务 0x038501c4 GSEventRunModal + 217
21 图形服务 0x03850289 GSEventRun + 115
22 UIKit 0x00614c93 UIApplicationMain + 1160
23 Wordfare 0x00002224 主 + 102
24 Wordfare 0x000021b5 开始 + 53
)
在抛出 'NSException' 实例后调用终止
对不起,双倍间距。我无法弄清楚格式。
看起来 __NSCFArray 在持久存储协调器被释放后碰巧移入,但仍有一个指向持久存储的指针并试图调用它的 tryLock。
真的很难说那会是什么。我分配持久存储协调器,调用 addPersistentStore,然后释放它并将其设置为 nil。我的代码中的任何内容都无法在该方法之外获得对它的引用。我能想象得到对它的引用的唯一一件事就是 managedObjectModel。我也尝试发布它,但出现了不同的错误。
如果我注释掉释放persistentStoreCoordinator 的行,并将其设置为nil,那么它运行良好,但这是不对的。 persistentStoreCoordinator 当然是一个实例变量。我分配了它;如果我放弃对它的引用,我应该释放它。
发生错误后我应该如何清理持久存储协调器?
附加:我已确认无法识别的选择器正在发送到持久存储协调器的内存地址。
【问题讨论】:
标签: ios core-data memory-management