我在 coredata NSManagedObjectContextDidSaveNotification 中运行一个谓词来过滤我感兴趣的相关对象。
- (void)didSaveNotficiation:(NSNotification*)notification
{
NSSet *objects = nil;
NSMutableSet *combinedSet = nil;
NSPredicate *predicate = nil;
NSDictionary *userInfo = [notification userInfo];
objects = [userInfo objectForKey:NSInsertedObjectsKey];
combinedSet = [NSMutableSet setWithSet:objects];
objects = [[notification userInfo] objectForKey:NSUpdatedObjectsKey];
[combinedSet unionSet:objects];
objects = [[notification userInfo] objectForKey:NSDeletedObjectsKey];
[combinedSet unionSet:objects];
//THis is slow
predicate = [NSPredicate predicateWithFormat:@"entity.name == %@ && %K == %@",
[XXContact entityName], XXContactRelationship.user,self];
[combinedSet filterUsingPredicate:predicate];
if ([combinedSet count] == 0) {
return;
}
[self process];
/* This is much faster
[combinedSet enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
if ([obj isKindOfClass:[XXContact class]]) {
XXContact* contact = (XXContact*)obj;
if (contact.user == self) {
[self process];
*stop = YES;
}
}
}];
*/
}
The notification can be called over 100 times when the app starts. When I profile the app, it seems that the function predicateWithFormat is so slow that is taking up 20% of cpu. It is not even the filtering that is slow. The creation of the predicate itself is so slow. If I change it to use enumerateObjectsUsingBlock, it becomes much faster, but the code is less readable.
Does anyone has a explanation? Thanks.