Core Data: Do child contexts ever get permanent objectIDs for newly inserted objects?

血红的双手。 提交于 2019-11-27 00:38:54

It is a known bug, hopefully fixed soon, but in general, obtaining a permanent ID is sufficient, provided you do so before you save the data in the first child, and you only include the inserted objects:

[moc obtainPermanentIDsForObjects:moc.insertedObjects.allObjects error:&error]

In some complex cases, it is better to get a permanent ID as soon as you create the instance, especially if you have complex relationships.

How and when are you calling obtainPermanentIDsForObjects?

I do not follow the part about the app crashing. Maybe a better explanation would help.

Dino Mic

As Jody said above, when creating a new NSManagedObject in a background thread using a child ManagedObjectContext you must force the creation of a permanent ID by doing the following BEFORE you save:

NSError *error = nil;

[threadedMOC obtainPermanentIDsForObjects:threadedMOC.insertedObjects.allObjects error:&error];

BOOL success = [threadedMOC save:&error];

IMHO, it's not really intuitive to do it this way - after all, you're asking for a permanent ID BEFORE you save! But this is the way it seems to work. If you ask for the permanent ID after the save, then the ID will still be temporary. From the Apple Docs, you can actually use the following to determine if the object's ID is temporary:

BOOL isTemporary = [[managedObject objectID] isTemporaryID];

Problem still exists in iOS 8.3 Solution in Swift :

func saveContext(context: NSManagedObjectContext?){
   NSOperationQueue.mainQueue().addOperationWithBlock(){
    if let moc = context {
        var error : NSError? = nil
        if !moc.obtainPermanentIDsForObjects(Array(moc.insertedObjects), error: &error){
            println("\(__FUNCTION__)\n \(error?.localizedDescription)\n \(error?.userInfo)")
        }
        if moc.hasChanges && !moc.save(&error){
            println("\(__FUNCTION__)\n \(error?.localizedDescription)\n \(error?.userInfo)")
        }
    }
 }
}

func saveBackgroundContext(){
    saveContext(self.defaultContext)

    privateContext?.performBlock{
        var error : NSError? = nil
        if let context = self.privateContext {

            if context.hasChanges && !context.save(&error){
                println("\(__FUNCTION__)\n \(error?.localizedDescription)\n \(error?.userInfo)")
            }else {
                println("saved private context to disk")
            }
        }
    }
}

Where:

  • defaultContext has concurrencyType .MainQueueConcurrencyType
  • privateContext has concurrencyType .PrivateQueueConcurrencyType
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!