我如何获得CPU 100%并阻止后台队列中的主线程。我这样做:
首先,我在自定义setter中创建上下文:
-(void)setContext:(NSManagedObjectContext *)context {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
_context = context;
});
}
然后我使用NSURLConnectionDataDelegate
下载一些数据,然后是我插入的方法:
-(void)connectionDidFinishWithObject:(NSArray*)arrayOfObjects {
dispatch_queue_t fetchQ = dispatch_queue_create("myDispatch", NULL);
dispatch_async(fetchQ, ^{
[self.context performBlock:^{
for(NSDictionary *dic in myArr) {
[Tournament tournamentWithDictionary:dic inMOC:self.context];
}
}];
}
}
这是我对NSManagedObject
子类的插入:
+(Tournament*)tournamentWithDictionary:(NSDictionary*)dictionary inMOC:(NSManagedObjectContext*)moc {
Tournament *finalElement;
if(!finalElement) {
finalElement = [NSEntityDescription insertNewObjectForEntityForName:@"Tournament" inManagedObjectContext:moc];
[finalElement setTournamentID:[NSNumber numberWithInt:[[dictionary objectForKey:@"ID"] integerValue]]];
}
return finalElement;
}
我获得了100%的CPU使用率并且我的界面是阻止的!为什么呢?!
答案 0 :(得分:2)
在调试器下运行并点击“暂停”以找出主线程正在做什么。使用Instruments来显示正在运行的代码来咀嚼CPU。
答案 1 :(得分:2)
您是否真的对代码进行了分析以查看消耗CPU的内容?
另外,您的托管对象上下文是如何配置的?具体来说,什么是并发类型?如果并发类型是NSMainQueueConcurrencyType,那么使用队列来导致上下文执行块将完全没有意义。
我建议你仔细阅读this documentation。
您在setter中使用dispatch_async
是不必要的,并且dispatch_async
使用connectionDidFinishWithObject:
到不同的队列会导致竞争条件}。
即。你的并发性被破坏了。
答案 2 :(得分:1)
我还不清楚你是如何在主队列上使用核心数据的,如果有的话,但通常的原因是:
NSManagedObject
属性; 对主队列的访问需要访问数据库,这通常是因为您正在访问的对象当前是一个错误 - 尽管任何其他数据库之旅都会有问题。因此,明确地执行NSFetchRequest
或具有必须执行某些工作的活动NSFetchedResultsController
,因为滚动都是等效条件。
可悲的是,SQLite不是线程安全的。部分结果是您在保存时无法访问数据库。如果您插入了大量条目,如果您有复杂的索引,或者出于其他一些原因,保存可能需要很长时间。
因此主队列需要同步到数据库,但Core Data必须等待保存完成。因此它必须阻止。