gpt4 book ai didi

ios - 在多个线程上访问 ViewContext 导致崩溃

转载 作者:行者123 更新时间:2023-12-01 19:52:10 29 4
gpt4 key购买 nike

我有两个 UIViewController s 在标签栏中

TabBar 之一中我正在使用 AFNetworking 进行 api 调用这个 api 调用将数据保存在 CoreData .

这是我的代码

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

for (int i = 0; i < cartList.count; i++)
{
NSDictionary *dict = [cartList objectAtIndex:i];
NSFetchRequest *request = [Orders fetchRequest];
request.predicate = [NSPredicate predicateWithFormat:@"orderId = %@", [dict objectForKey:kiD]];

NSError *error = nil;
NSArray *itemsList = context executeFetchRequest:request error:&error];
if (itemsList.count == 0)
{
Orders *order = [NSEntityDescription insertNewObjectForEntityForName:@"Orders" inManagedObjectContext:appDel.persistentContainer.viewContext];
[order updateWithDictionary:dict];
order.isNew = NO;
}
else
{
Orders *order = [itemsList objectAtIndex:0];
[order updateWithDictionary:dict];
order.isNew = NO;
}
}

dispatch_async(dispatch_get_main_queue(), ^{

[appDel saveContext];
[self refreshValues:NO];

});
});

在第二 VIewController我正在做类似的事情。如果我非常快地切换选项卡 Controller ,应用程序会崩溃
 [appDel saveContext];

很可能是因为上次 viewContext被其他 UIviewController 使用在后台线程中。

我可以采取什么解决方法来解决这个问题

如果正确实现
[appDel.persistentContainer performBackgroundTask:^(NSManagedObjectContext * _Nonnull context)
{
NSFetchRequest *request = [Categories fetchRequest];
NSBatchDeleteRequest *deleteReq = [[NSBatchDeleteRequest alloc] initWithFetchRequest:request];

NSError *deleteError = nil;
[appDel.persistentContainer.viewContext executeRequest:deleteReq error:&deleteError];

for (int i = 0; i < dataArr.count; i++)
{
Categories *category = [NSEntityDescription insertNewObjectForEntityForName:@"Categories" inManagedObjectContext:appDel.persistentContainer.viewContext];
[category updateWithDictionary:[dataArr objectAtIndex:i]];
}

@try {

NSError *error = nil;
[context save:(&error)];
} @catch (NSException *exception)
{
}

[self getCategoryItems];
}];

最佳答案

核心数据不是线程安全的,也不是为了阅读而写作。如果您违反此规则,核心数据可能会以意想不到的方式失败。因此,即使它看起来有效,您也会发现核心数据突然无缘无故崩溃。换句话说,从错误的线程访问核心数据是未定义的。

有几种可能的解决方案:

1) 只使用主线程读写核心数据。对于不进行大量数据导入或导出且数据​​集相对较小的简单应用程序,这是一个不错的解决方案。

2) 换行NSPersistentContainerperformBackgroundTask在操作队列中,仅通过该方法写入核心数据,从不写入 viewContext .当您使用 performBackgroundTask该方法为您提供了上下文。您应该使用上下文来获取您需要的任何对象,修改它们,保存上下文,然后丢弃上下文和对象。

如果您尝试同时使用 performBackgroundTask并直接写信给viewContext您可能会遇到写入冲突并丢失数据。

关于ios - 在多个线程上访问 ViewContext 导致崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45161590/

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