0

我怎么可能获得 100% 的 CPU 并阻塞后台队列中的主线程。我这样做:

首先,我在自定义设置器中创建上下文:

-(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;
}

而且我的 CPU 使用率达到 100%,而且我的界面被阻塞了!为什么?!

4

3 回答 3

2

Did you actually profile your code to see what is consuming the CPU?

Also, how is your managed object context configured? Specifically, what is the concurrency type? Your use of a queue to cause the context to perform a block is going to be entirely pointless if the concurrency type is NSMainQueueConcurrencyType.

I'd suggest you read this documentation closely.


Your use of that dispatch_async in the setter is both unnecessary and it will lead to a race condition with the use dispatch_async to a different queue in connectionDidFinishWithObject:.

I.e. your concurrency is busted.

于 2013-06-13T19:24:13.513 回答
2

在调试器下运行并点击“暂停”以找出主线程在做什么。使用 Instruments 显示哪些代码正在运行以占用 CPU。

于 2013-06-13T17:37:10.587 回答
1

我还不清楚你如何在主队列上使用 Core Data,如果有的话,但通常的原因是:

  1. 你已经使用了 SQLite 持久存储;
  2. 您正在访问NSManagedObject主队列上的某些属性;
  3. 同时,您正在保存其他队列。

对主队列的访问需要访问数据库,这通常是因为您正在访问的对象当前是一个错误——尽管任何其他访问数据库都会有同样的问题。所以做一个NSFetchRequest明确的或有一个NSFetchedResultsController必须做一些工作的活动,比如说,由于滚动都是等价的条件。

可悲的是 SQLite 不是线程安全的。部分原因是您在保存时无法访问数据库。如果您插入了很多条目,如果您有复杂的索引,或者由于许多其他原因,保存可能需要很长时间。

所以主队列想要同步到数据库,但 Core Data 必须等待保存完成。因此它必须阻塞。

于 2013-06-13T19:40:51.283 回答