gpt4 book ai didi

ios - 如何在正确的队列上初始化 ManagedObjectContext?

转载 作者:行者123 更新时间:2023-11-29 00:30:31 27 4
gpt4 key购买 nike

非常需要建议,目前没有想法。我与核心数据并发相关的问题叠加在一起,调试我使用 -"com.apple.CoreData.ConcurrencyDebug"和我所拥有的:

堆栈:

线程 3 队列:coredata(serial)

0 +[NSManagedObjectContext Multithreading_Violation_AllThatIsLeftToUsIsHonor]: CoreData`-[NSManagedObjectContext executeFetchRequest:error:]:

1 -[NSManagedObjectContext executeFetchRequest:error:]:

2 NSManagedObjectContext.fetch (__ObjC.NSFetchRequest) throws -> Swift.Array:

3 AppDelegate.(fetchRequest NSFetchRequest) -> [A]).(closure #1)

我从这里进入 AppDelegate::fetchRequest:

let messageRequest: NSFetchRequest<ZMessage> = ZMessage.fetchRequest();
messageRequest.sortDescriptors = [NSSortDescriptor(key: "id", ascending: false)];
let messageArray: Array<ZMessage> = self.fetchRequest(messageRequest);

我在串行队列 (self.queueContainer) 上执行所有核心数据。

public func fetchRequest<T>(_ request: NSFetchRequest<T>) -> Array<T>
{
var retval: Array<T> = Array<T>();
self.queueContainer.sync {
do {
retval = try self.persistentContainer.viewContext.fetch(request);
} catch {
let nserror = error as NSError;
fatalError("[CoreData] Unresolved fetch error \(nserror), \(nserror.userInfo)");
}
}
return retval;
}

这是我发现有用的。

Below are some of the rules that must be followed if you do not want your app that uses CoreData to crash (or) corrupt the database:

A NSManagedObjectContext should be used only on the queue that is associated with it.

If initialized with .PrivateQueueConcurrencyType, a private, internal queue is created that is associated with the object. This queue can be accessed by instance methods .performBlockAndWait (for sync ops) and .performBlock (for async ops)

If initialized with .MainQueueConcurrencyType, the object can be used only on the main queue. The same instance methods ( performBlock and performBlockAndQueue) can be used here as well. An NSManagedObject should not be used outside the thread in which it is initialized

现在我正在四处挖掘,但老实说不能确定我的托管对象上下文 (MOC) 是否与正确的队列相关联。

来自手册:

...A consequence of this is that a context assumes the default owner is the thread or queue that allocated it—this is determined by the thread that calls its init method.

在 AppDelegate 中,我不直接使用 MOC 进行操作,而是实例化拥有此 MOC 的 NSPersistentContainer。以防万一我也在同一个串行队列上执行此操作。

public lazy var persistentContainer: NSPersistentContainer =
{
self.queueContainer.sync {
let container = NSPersistentContainer(name: "Joker")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})

return container
}
}()

提前致谢。

最佳答案

我不是 Swift 编码员,但是什么是queueContainer?

您不应该自己执行线程,您应该使用 NSManagedObjectContext block methods正如您在引文中所写:

The same instance methods ( performBlock and performBlockAndQueue) can be used here as well.

managedObjectContext.performBlock {

无论您使用什么 ManagedObjectContext,您都应该使用该上下文 block 方法并在 block 方法内执行您的操作。

Look at the documentation这里有关于如何正确执行此操作的示例。

还可以避免崩溃和线程错误:

NSManagedObject instances are not intended to be passed between queues. Doing so can result in corruption of the data and termination of the application. When it is necessary to hand off a managed object reference from one queue to another, it must be done through NSManagedObjectID instances.

You retrieve the managed object ID of a managed object by calling the objectID method on the NSManagedObject instance.

关于ios - 如何在正确的队列上初始化 ManagedObjectContext?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41988409/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com