我只是想弄清楚核心数据私有上下文。我正在尝试使用私有上下文(NSPrivateQueueConcurrencyType)插入20k记录。但是,一旦点击“插入20k条记录”按钮,UI线程就会挂起。
- (IBAction)insertRecords:(id)sender {
[[CoreDataStore privateContext] performBlock:^{
NSLog(@"Starting to insert 20k records...");
for (int i = 0 ; i < 20000; i++)
{
NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:[CoreDataStore privateContext]];
[newManagedObject setValue:[NSDate date] forKey:@"time"];
}
NSError * error = nil;
NSLog(@"Inserted 20k records to managed object context");
[[CoreDataStore privateContext] save:&error];
NSLog(@"Save context command fired");
}];
NSLog(@"returning from insert method");
}
从私有上下文的更改正在合并到主要上下文
- (void)contextDidSavePrivateQueueContext:(NSNotification *)notification
{
@synchronized(self) {
[self.mainContext performBlock:^{
NSLog(@"merging changes to main context.....");
[self.mainContext mergeChangesFromContextDidSaveNotification:notification];
NSLog(@"merged changes to main context");
}];
}
}
下面是当我点击插入按钮时的日志窗口输出:
2014-08-04 14:54:12.431 CoreDataDrillDown[11323:90b] returning from insert method
2014-08-04 14:54:12.431 CoreDataDrillDown[11323:1403] Starting to insert 20k records...
2014-08-04 14:54:12.506 CoreDataDrillDown[11323:1403] Inserted 20k records to managed object context
2014-08-04 14:54:12.785 CoreDataDrillDown[11323:90b] merging changes to main context.....
2014-08-04 14:54:12.786 CoreDataDrillDown[11323:1403] Save context command fired
2014-08-04 14:54:27.019 CoreDataDrillDown[11323:90b] merged changes to main context
超过15秒钟,UI一直没有响应。我想知道为什么吗?
使用https://stackoverflow.com/users/817182/thom-ek和https://stackoverflow.com/users/2128900/micha%c5%82-ciuba建议的以下方法,插入速度很快,并且不会冻结UI,但是更改不会保存到磁盘,不确定原因。
//writerContext has persistent store coordinator, so it should write data to disk but it
//is not writing any changes to disk.???????
-(NSManagedObjectContext *)writerContext
{
if (!_writerContext)
{
_writerContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
_writerContext.persistentStoreCoordinator = [(AppDelegate *)[[UIApplication sharedApplication] delegate] persistentStoreCoordinator];
}
return _writerContext;
}
//mainContext is being used with NSFetchedResultController
-(NSManagedObjectContext *)mainContext
{
if (!_mainContext)
{
_mainContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
_mainContext.parentContext = [self writerContext];
}
return _mainContext;
}
//performBlock is being called on privateContext
-(NSManagedObjectContext *)privateContext
{
if (!_privateContext)
{
_privateContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
_privateContext.parentContext = [self mainContext];
}
return _privateContext;
}
最佳答案
主要问题是mainContext仍与mainQueue绑定,因此它将等待此巨大的合并。
关于异步保存的好文章:Cocoanetics和ObjC.io上。
另一种解决方案是重置mainContext并重新加载所有tableViews(您不会一次向用户显示所有20k条记录)。
关于ios - iOS:核心数据performBlock使UI无响应,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25115563/