PrivateQueueConcurrencyType 导致 CoreData 内存泄漏

Jus*_*ght 5 memory-leaks core-data ios swift

我今天发现了内存泄漏,当 从我的NSManagedObjectContext调用executeFetchRequest时,它就显现出来了。我最终发现已知的罪犯是因为我的 NSManagedObjectContext 将它\xe2\x80\x99s 父上下文分配给了私有托管对象上下文。

\n\n

注释掉我的主上下文分配私有父类的代码行,而不是直接指向 NSPersistentStoreCoordinator 可以释放我的应用程序的所有内存泄漏。

\n\n

我正在阅读以下文章:http://martiancraft.com/blog/2015/03/core-data-stack/,了解如何在我的应用程序中实现 CoreData 的设计模式。我真的很喜欢这样的想法:让一个专用队列专门用于写入磁盘,并将主上下文作为使用 UI 时调用的单一来源。

\n\n

所以我的问题是,是否有其他人遇到过这个问题,如果是的话,您是否知道解决方法,而不是仅仅在一个上下文上工作以避免内存泄漏?

\n\n

下面是我的 CoreDataStack 的部分,显示了两个上下文变量。

\n\n
private lazy var privateManagedObjectContext: NSManagedObjectContext = {\n    let moc = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)\n    moc.persistentStoreCoordinator = self.persistentStoreCoordinator\n    return moc\n  }()\n\n  lazy var managedObjectContext: NSManagedObjectContext = {\n    let managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)\n\n    // Commenting out  #1 and unCommening #2 prevents the leak from happening\n    // However when the reverse happens and we create the private context, a memory leak occurs first thing in the app.\n\n    // #1\n    // managedObjectContext.parentContext = self.privateManagedObjectContext\n\n    // And instead replace it with this line\n    // #2\n    managedObjectContext.persistentStoreCoordinator = self.persistentStoreCoordinator\n\n\n    return managedObjectContext\n  }()\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是我使用主和私有托管对象上下文的保存方法。

\n\n
func save() {\n    guard managedObjectContext.hasChanges || privateManagedObjectContext.hasChanges else {\n      return\n    }\n\n    print("Going to save now")\n\n    managedObjectContext.performBlockAndWait() {\n      do {\n        try self.managedObjectContext.save()\n      } catch {\n        fatalError("Error saving main managed object context! \\(error)")\n      }\n    }\n\n    privateManagedObjectContext.performBlock() {\n      do {\n        try self.privateManagedObjectContext.save()\n      } catch {\n        fatalError("Error saving private managed object context! \\(error)")\n      }\n    }\n\n  }\n
Run Code Online (Sandbox Code Playgroud)\n

Abo*_*ods 3

private lazy var privateManagedObjectContext: NSManagedObjectContext = {\n  let moc = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)\n  moc.parent = managedObjectContext // Set the receiver\xe2\x80\x99s parent context\n  return moc\n}()\n
Run Code Online (Sandbox Code Playgroud)\n\n

也许这可以解决这个问题。

\n