gpt4 book ai didi

ios - 核心数据 : Can only use -performBlock: on an NSManagedObjectContext that was created with a queue

转载 作者:搜寻专家 更新时间:2023-10-31 22:52:45 24 4
gpt4 key购买 nike

我不确定这是怎么回事,但我需要一些帮助。每次用户在 UITextField 中输入文本时,我都试图在后台执行查询。我一直在阅读,看起来我应该如何执行后台 CoreData 操作,但我不断收到此错误:

“只能在使用队列创建的 NSManagedObjectContext 上使用 -performBlock:”

我用谷歌搜索了这个错误,但每个解决方案都说我的上下文需要使用 PrivateQueueConcurrentcyType 创建,我确实这样做了。不知道为什么会这样。也许这是新 iOS 中的错误?

let managedObjectContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = appDelegate.persistentStoreCoordinator
if !textField.text.isEmpty {
manatedObjectContext.performBlock {
let objectIDs = //query to get the object IDs

appDelegate.managedObjectContext.performBlock {
var objects = Object[]()

for id in objectsIDs {
objects += appDelegate.managedObjectContext.objectWithID(id) as Object
}

self.searchResults = objects
self.searchResultsTableView.reloadData()
}
}
}

编辑:我通过执行以下操作解决了我的问题:

  • 将私有(private) managedObjectContext 的父上下文设置为 AppDelegate 的主要上下文
  • 我删除了设置持久存储的行,因为在将父上下文设置为主上下文时不再需要它
  • 我还更改了创建主上下文的默认实现,以使用 MainQueueConcurrencyType 显式创建它

最佳答案

示例取自实际发布的应用,您应该使用 2+ MOC。

  1. 一个用于主线程
  2. 每个后台线程一个。

这允许后台线程安全地执行 MOC 操作,而不会冒相互冲突的风险。注意辅助 MOC 如何使用 -setParentContext: 来引用主 MOC。

这个backgroundMOC,当从后台线程创建和使用时,是安全的,不会抛出错误。

完成修改后,在后台线程上执行保存:

[backgroundMOC performBlockAndWait:^{
if([backgroundMOC hasChanges]) {
NSError * error;
[backgroundMOC save:&error];
// handle error
}
}];

要创建上面示例中使用的两个 MOC,您可以使用下面的代码 (ObjC)

对于主线程,使用:

@property(strong) NSManagedObjectContext * 

- (NSManagedObjectContext *)mainMOC mainManagedObjectContext;
{
NSThread * currentThread = [NSThread currentThread];
NSAssert([currentThread isMainThread], @"managedObjectContext invoked from %@",currentThread);
if([currentThread isMainThread]) {
if(!_mainManagedObjectContext) {
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];

if(coordinator) {
_mainManagedObjectContext = [[NSManagedObjectContext alloc]
initWithConcurrencyType:NSMainQueueConcurrencyType];
[_mainManagedObjectContext setPersistentStoreCoordinator: coordinator];
[_mainManagedObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
}
}

return _mainManagedObjectContext;
}
return nil;
}

对于后台线程,使用:

- (NSManagedObjectContext *)threadMOCWithMainMOC:(NSManagedObjectContext *)mainMOC
{
NSManagedObjectContext * threadManagedObjectContext = [[NSManagedObjectContext alloc]
initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[threadManagedObjectContext setParentContext:[self.db mainManagedObjectContext]];
[threadManagedObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
return threadManagedObjectContext;
}

关于ios - 核心数据 : Can only use -performBlock: on an NSManagedObjectContext that was created with a queue,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24601297/

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