robbiehanson / XMPPFramework

An XMPP Framework in Objective-C for Mac and iOS
Other
5.91k stars 2.09k forks source link

Accessing XMPPUserCoreDataStorageObject objects from mergeChangesFromContextDidSaveNotification call #27

Closed mannyvw closed 12 years ago

mannyvw commented 12 years ago

Hi

Am quite new XMPPFramework and am porting an existing app from using old version of XMPP that had a XMPPStreamFacebook stream to the new framework which just has XMPPStream and initWithFacebookAppId constructor. Am nearly there, everything seems to work, at least the first time, the 2nd time i run the app i have problems when mergeChangesFromContextDidSaveNotification calls my controllerWillChangeContent, this function access objects via my NSFetchedResultsController that has been setup on the main thread, it was created with object returned by mainThreadManagedObjectContext. Is this correct ? It seems when i try and access the actual objects it crashes because they were created within XMPPFramework on another thread and as we know CoreData is not thread safe. Whats easiest fix ?

thanks

mannyvw commented 12 years ago

Managed to fix it by removing NSFetchedResultsController, subclassing XMPPRosterCoreDataStorage, implementing custom mainThreadManagedObjectContextDidMergeChanges and executing fetch on demand removing need for dynamic NSFetchedResultsController, seems to work well, although i did have to call [m_xmppRosterStorage mainThreadManagedObjectContext] even though i didnt need it until the callback was triggered just to get the notification registered.

cheers. great library, I also now know a lot more about ARC and building apps without ARC support on top of libraries that use it ;-)

robbiehanson commented 12 years ago

Glad you got it fixed. Not sure exactly what problem you were having, but it sounds like you've come up with a workable solution.

Not sure if this had anything to do with it, but you have to be careful with NSManagedObjects. They are attached to a particular thread/queue and NSManagedObjectContext. So you can't pass them between threads. Instead you have to pass the managedObject.objectID, and then use various mechanisms to grab the element from the objectID. Core Data is one of those powerful but complicated technologies..