I have an NSOperation subclass which uses Core Data.
It has a custom init method like this:
- (id)initWithManagedObjectContext:(NSManagedObjectContext*)moc;
As you may know, Core Data managed object contexts are not thread-safe and every thread needs it’s own managed object context. When creating this NSOperation, I create a new NSManagedObjectContext and pass it as the moc argument to the initializer.
Here’s the important part: When initializing, I register for a notification:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(managedObjectContextDidSave:) name:NSManagedObjectContextDidSaveNotification object:moc];
In -dealloc I unregister from the NotificationCenter:
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:nil];
}
Before I migrated to ARC, this code worked perfectly fine.
Now under ARC, I get a stack trace like this:
1) The NSOperation object receives -dealloc
2) -removeObserver:name:object: is called on the NSNotificationCenter.
3) __arclite_objc_release
4) The NSOperation object receives -dealloc
5) -removeObserver:name:object: is called on the NSNotificationCenter.
6) __arclite_objc_release
7) The NSOperation object receives -dealloc
8) -removeObserver:name:object: is called on the NSNotificationCenter.
9) __arclite_objc_release
This continues forever. -dealloc, unregister from notification center, __arclite_objc_release, -dealloc, …
It seems like if __arclite_objc_release triggeres a call to -dealloc even though the NSOperation object has been destroyed!
How is this possible?
Update: For some insanely weird reason the infinite loop to -dealloc disappeared after I changed my notification center unregistration code to this:
[[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:self.managedObjectContext];
So instead of simply unregistering for any notification sent by any sender, I explicitely unregister for any notification sent by a particular sender.
The obvious problem is this: Since ARC inserts code into -dealloc, I don’t know if it is inserted before my -dealloc code, or after my -dealloc code.
Reading your update, it seems you should call
[super dealloc]in a different place than where you are (if you are). Try calling it first thing in the dealloc method, then unregister yourNSNotification