Core data的batch update

关于Core data最大的抱怨是缺乏批处理操作。比如RSS阅读器这种需要在众多entities上操作的应用,没有批处理操作就必须将所有东西装入内存,然后手动设置必要的attributes.

通常你会这么操作:

NSFetchRequest *fetchAllRSSItems = [NSFetchRequest fetchRequestWithEntityName:[RSSItem entityName]];
NSError *fetchError;
NSArray *results = [self.managedObjectContext executeFetchRequest:fetchAllRSSItems error:&fetchError];


if (results == nil) {
    NSLog(@"@"Error: %@", [fetchError localizedDescription]);  
} else {
    for (RSSItem *rssItem in results) {
        rssItem.read = [NSNumber numberWithBool:YES];
    }

    [self saveManagedObjectContext];


}

如果你使用一个主线程的managed object context, 你将会阻塞UI。你可以通过一个私有的managed object context来消除阻塞,但是这种操作仍然是耗时的。

在内存有限的设备,如iPhone上,将所有的entities放进内存甚至有可能做不到。为了解决内存问题,必须分批操作,但是这样做并不会加快操作。这种分批操作只好向用户显示一个进度条。

在iOS8和OS X Yosemite上,你再也不用将所有entities装进内存,手动设置attributes.

NSBatchUpdateRequest *batchRequest = [NSBatchUpdateRequest batchUpdateRequestWithEntityName:[RSSItem entityName]];
batchRequest.propertiesToUpdate = @{NSStringFromSelector(@selector(read)):[NSNumber numberWithBool:YES]};
batchRequest.resultType = NSStatusOnlyRequestType; // NSStatusOnlyResultType is the default
batchRequest.affectedStores = @[...]; // Optional, stores this request should be sent to
batchRequest.predicate = [NSPredicate predicateWithFormat:@"..."]; // Optional, same type of predicate you use on NSFetchRequest

NSError *requestError;
NSBatchUpdateResult *result = (NSBatchUpdateResult *)[self.managedObjectContext executeRequest:batchRequest error:&requestError];

if (result == nil) {

    NSLog(@"Error: %@", [requestError localizedDescription]);
} else {

    // Batch update succeeded
}

当执行executeRequest:error:时,它将跨过managedObjectContext,直接update persistent store. 由于在context上没有任何改变的反映,所以该过程不会执行验证机制,所以必须小心。

如果需要在batch 操作完成之后update UI,那么可以讲batch request的resultType设为NSUpdatedObjectIDsResultType. 一旦有了IDs, 就可以通过主moc获取entities来更新UI.

如果并不关心实际的entities,而是想知道change是否发生,可以将resultType设置为NSUpdateObjectsCountResultType.当批处理完成之后,结果属性中会有一个NSNumber的变量存储改变的entities的数量。

posted @ 2015-02-16 17:01  jokerlu  阅读(608)  评论(0编辑  收藏  举报