I am getting an error that seems pretty clearly to be a message to a deallocated object, but I cannot figure out where I am managing memory wrong. This is my code to create the persistent store coordinator. It's based on the Core Data application template. I might have changed it a bit, but not much I think.
- (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;
}
The problem happens when I get an error from addPersistentStore, because I changed my model and I'm trying to open a store that was created with the previous model. Of course one answer is, "Don't do that." I won't, but I want the code to be robust. The above code runs without complaint, but then when I press the home button, the app crashes with this error:
2011-11-02 16:39:53.751 Wordfare[11137:207] -[__NSCFArray tryLock]: unrecognized selector sent to instance 0x5a122f0
2011-11-02 16:39:53.783 Wordfare[11137:207] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFArray tryLock]: unrecognized selector sent to instance 0x5a122f0'
* Call stack at first throw:
(
0 CoreFoundation 0x012ed5a9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x01441313 objc_exception_throw + 44
2 CoreFoundation 0x012ef0bb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x0125e966 forwarding + 966
4 CoreFoundation 0x0125e522 _CF_forwarding_prep_0 + 50
5 CoreData 0x010d9ef0 -[_NSSQLCoreConnectionObsever _purgeCaches:] + 112
6 Foundation 0x00370669 _nsnote_callback + 145
7 CoreFoundation 0x012c59f9 __CFXNotificationPost_old + 745
8 CoreFoundation 0x0124493a _CFXNotificationPostNotification + 186
9 Foundation 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 GraphicsServices 0x03851992 PurpleEventCallback + 1550
15 CoreFoundation 0x012ce944 CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION + 52
16 CoreFoundation 0x0122ecf7 __CFRunLoopDoSource1 + 215
17 CoreFoundation 0x0122bf83 __CFRunLoopRun + 979
18 CoreFoundation 0x0122b840 CFRunLoopRunSpecific + 208
19 CoreFoundation 0x0122b761 CFRunLoopRunInMode + 97
20 GraphicsServices 0x038501c4 GSEventRunModal + 217
21 GraphicsServices 0x03850289 GSEventRun + 115
22 UIKit 0x00614c93 UIApplicationMain + 1160
23 Wordfare 0x00002224 main + 102
24 Wordfare 0x000021b5 start + 53
)
terminate called after throwing an instance of 'NSException'
Sorry for the double-spacing. I couldn't figure out the formatting.
It looks like an __NSCFArray has happened to move in after the persistent store coordinator was deallocated, but something still has a pointer to the persistent store and is trying to call its tryLock.
It's really hard to tell what that could be. I allocate the persistent store coordinator, call addPersistentStore, then release it and set it to nil. Nothing in my code could have got a reference to it outside that method. The only thing I can imagine getting a reference to it would be the managedObjectModel. I tried releasing that too but that got a different error.
If I comment out the line that releases persistentStoreCoordinator, and just set it to nil, then it runs fine, but that can't be right. persistentStoreCoordinator is an instance variable of course. I allocated it; I should release it if I'm discarding the reference to it.
How am I supposed to clean up a persistent store coordinator after an error?
Additional: I have confirmed that the unrecognized selector is getting sent to the memory address of the persistent store coordinator.
Not a Core Data answer, but you should run with zombies enabled (in recent Xcodes, just hit the checkbox in the Debug part of the scheme).
User contributions licensed under CC BY-SA 3.0