Update
I wrote a minimal code example of the issue I am having. I implemented the background work two ways: manually spawning threads and letting NSOperation handle threading. In both cases I am creating NSManagedObjectContexts for each thread/operation.
When I spawn the threads myself with performSelectorInBackground:withObject: everything works fine. When I switch to passing my objects off to an NSOperationQueue I see the following errors when attempting to save the operations NSManagedObjectContext.
- EXC_BAD_ACCESS
- Serious application error. Exception was caught during Core Data change processing: * -[NSCFSet addObject:]: attempt to insert nil with userInfo (null)
- _referenceData64 only defined for abstract class. Define -[NSTemporaryObjectID_default _referenceData64]!
I believe the bug, especially given the last error, has to do with using a temporary objectID to pass objects between threads/contexts. Possibly, even worse, I'm somehow passing NSManagedObjects between threads.
Either way, I can't find any code which would suggest I am doing so.
My minimal code example can be found at http://matthewcrandall.net/MinimalCodeExample.zip
Most of the work is done in the AppDelegate in awakeFromNib. Set EXECUTE_WITH_NSOPERATION to 0 to run with performSelectorInBackground:withObject:. Leave EXECUTE_WITH_NSOPERATION on 1 to execute with the NSOperationQueue which creates a bunch of MCBoardParse objects.
I'm only seeing this under 10.6.
Original
I have a Cocoa application built on 10.5 frameworks. In an NSOperation In a loop I am quickly creating hundreds of NSManagedObjects. Frequently the creation of those NSManagedObejcts will crash with a exc_bad_access error. This happens under both reference counted memory management and garbage collection.
for (offsetCount; offsetCount < [parsedData count]; offsetCount++) {
NSManagedObject *child = [NSEntityDescription insertNewObjectForEntityForName:@"Thread" inManagedObjectContext:[self moc]];
Thumbnail *thumb = [Thumbnail insertInManagedObjectContext:[self moc]];
Image *image = [Image insertInManagedObjectContext:[self moc]];
...
}
Thumbnail and Image are both subclasses of NSManagedObject generated with mogenerator. insertInManagedObjectContext: looks like
NSParameterAssert(moc_);
return [NSEntityDescription insertNewObjectForEntityForName:@"Thumbnail" inManagedObjectContext:moc_];
NSParameterAssert(moc_);
return [NSEntityDescription insertNewObjectForEntityForName:@"Image" inManagedObjectContext:moc_];
The NSManagedObjectContext returned by [self moc] is created for the NSOperation with
NSPersistentStoreCoordinator *coord = [(MyApp_AppDelegate *)[[NSApplication sharedApplication] delegate] persistentStoreCoordinator];
self.moc = [[NSManagedObjectContext alloc] init];
[self.moc setPersistentStoreCoordinator:coord];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(contextDidSave:)
name:NSManagedObjectContextDidSaveNotification
object:self.moc];
[self.moc setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
[self.moc setUndoManager:nil];
[self.moc setRetainsRegisteredObjects:YES];
moc is defined as (nonatomic, retain) and synthesized. As far as I can tell it, the persistent store and my appDelegate have no reason to be and are not being garbage collected.
The stack trace looks like
Thread 2 Crashed: Dispatch queue: com.apple.root.default-priority
0 libauto.dylib 0x00007fff82d63600 auto_zone_root_write_barrier + 688
1 libobjc.A.dylib 0x00007fff826f963b objc_assign_strongCast_gc + 59
2 com.apple.CoreFoundation 0x00007fff88677068 __CFBasicHashAddValue + 504
3 com.apple.CoreFoundation 0x00007fff88676d2f CFBasicHashAddValue + 191
4 com.apple.CoreData 0x00007fff82bdee5e -[NSManagedObjectContext(_NSInternalAdditions) _insertObjectWithGlobalID:globalID:] + 190
5 com.apple.CoreData 0x00007fff82bded24 -[NSManagedObjectContext insertObject:] + 148
6 com.apple.CoreData 0x00007fff82bbd75c -[NSManagedObject initWithEntity:insertIntoManagedObjectContext:] + 716
7 com.apple.CoreData 0x00007fff82bdf075 +[NSEntityDescription insertNewObjectForEntityForName:inManagedObjectContext:] + 101
8 com.yourcompany.MyApp 0x000000010002c7a7 +[_Thumbnail insertInManagedObjectContext:] + 256 (_Thumbnail.m:14)
9 com.yourcompany.MyApp 0x000000010002672d -[ThreadParse main] + 10345 (ThreadParse.m:174)
10 com.apple.Foundation 0x00007fff85ee807e -[__NSOperationInternal start] + 698
11 com.apple.Foundation 0x00007fff85ee7d23 ____startOperations_block_invoke_2 + 99
12 libSystem.B.dylib 0x00007fff812bece8 _dispatch_call_block_and_release + 15
13 libSystem.B.dylib 0x00007fff8129d279 _dispatch_worker_thread2 + 231
14 libSystem.B.dylib 0x00007fff8129cbb8 _pthread_wqthread + 353
15 libSystem.B.dylib 0x00007fff8129ca55 start_wqthread + 13
My app is crashing in other places with exc_bad_access but this is code that it happens most with. All of the stack traces look similar and have something to do with CFHash.
Any help would be appreciated.