【发布时间】:2014-07-27 13:11:51
【问题描述】:
我在这里寻找解决我的问题的方法,例如:
Core Data Saves and UI Performance
Why does Core Data take so long to save an object?
很多人都有我的问题,但我尝试使用他们的解决方案没有成功。
这是我的问题:
我正在尝试在后台的 Core Data 中保存 10 个托管对象。我没有任何错误,一切都很好,但是......保存 10 个对象需要 13 秒!我不知道我做错了什么......
我需要在我的数据库中保存 100 个对象,如果只有 10 个对象需要 13 秒...当我尝试保存 100 个时,我真的很害怕会发生什么。
这是我的代码:
首先,我在后台调用我的保存函数:
[self performSelectorInBackground:@selector(updateMessageList:) withObject:response];
我在这里保存对象:
- (void)updateMessageList:(NSArray *)messageList
{
AppDelegate *app = (AppDelegate *)[UIApplication sharedApplication].delegate;
NSManagedObjectContext *tmpContext = [[NSManagedObjectContext alloc]init];
tmpContext.persistentStoreCoordinator = [app persistentStoreCoordinator];
NSError *error;
int i = 0; //Counter to log how long it takes to insert a managedObject.
for (MessageReadResponse* messageUpdate in messageList) {
NSLog(@"%d", i++);
Message *message = [NSEntityDescription insertNewObjectForEntityForName:MESSAGE_ENTITY
inManagedObjectContext:tmpContext];
[message setState:STATE_ACTIVE];
[message setFromName:[[messageUpdate from]name]];
[message setFromSurname:[[messageUpdate from]surname]];
[message setBody:[messageUpdate body]];
}
NSLog(@"Before saving");
if (![tmpContext save:&error]) {
ErrorLog(@"%@", error.description);
[ErrorManagement synchronizeApplication];
return;
}
NSLog(@"After saving");
}
这是我在主线程中合并 managedObjectContext 的地方:
- (void)manageDidSaveNotification:(NSNotification *)notification
{
NSManagedObjectContext *savedContext = [notification object];
// Ignore change notifications for the main MOC
if (__managedObjectContext == savedContext)
{
return;
}
if (__managedObjectContext.persistentStoreCoordinator != savedContext.persistentStoreCoordinator)
{
// That's another database
return;
}
dispatch_sync(dispatch_get_main_queue(), ^{
[__managedObjectContext mergeChangesFromContextDidSaveNotification:notification];
});
}
这是我的性能日志:
2014-06-06 11:12:07.207 app-ios-client[260:8017] 0
2014-06-06 11:12:07.210 app-ios-client[260:8017] 1
2014-06-06 11:12:07.217 app-ios-client[260:8017] 2
2014-06-06 11:12:07.219 app-ios-client[260:8017] 3
2014-06-06 11:12:07.221 app-ios-client[260:8017] 4
2014-06-06 11:12:07.255 app-ios-client[260:8017] 5
2014-06-06 11:12:07.257 app-ios-client[260:8017] 6
2014-06-06 11:12:07.259 app-ios-client[260:8017] 7
2014-06-06 11:12:07.289 app-ios-client[260:8017] 8
2014-06-06 11:12:07.293 app-ios-client[260:8017] 9
2014-06-06 11:12:07.304 app-ios-client[260:8017] Before saving
2014-06-06 11:12:20.900 app-ios-client[260:8017] After saving
非常感谢!
已编辑:
Here 是我的仪器跟踪。
编辑 2:
感谢 Marcus Zarra,我发现这种方法会使我的应用程序运行得太慢:
-(CGFloat)getLabelHeightForIndex:(NSInteger)index
{
NSIndexPath *path = [NSIndexPath indexPathForRow:0 inSection:index];
UITextView *gettingSizeLabel = [[UITextView alloc] init];
gettingSizeLabel.font = [UIFont fontWithName:@"Helvetica" size:FONT_SIZE];
gettingSizeLabel.text = [[_fetchedResultsController objectAtIndexPath:path]body];
Message *info = [_fetchedResultsController objectAtIndexPath:path];
if ([[info contentSize]isEqualToString:@"(null)"]) {
CGSize maximumLabelSize = CGSizeMake(LABEL_WIDTH_NO_MEDIA, LABEL_TEXT_MAX_HEIGHT);
CGSize expectedSize = [gettingSizeLabel sizeThatFits:maximumLabelSize];
if (expectedSize.height < LABEL_TEXT_MIN_HEIGHT_NO_MEDIA) {
return LABEL_TEXT_MIN_HEIGHT_NO_MEDIA;
}
return expectedSize.height;
} else {
CGSize maximumLabelSize = CGSizeMake(LABEL_WIDTH_MEDIA, LABEL_TEXT_MAX_HEIGHT);
CGSize expectedSize = [gettingSizeLabel sizeThatFits:maximumLabelSize];
if (expectedSize.height < LABEL_TEXT_MIN_HEIGHT_MEDIA) {
return LABEL_TEXT_MIN_HEIGHT_MEDIA;
}
return expectedSize.height;
}
}
这个方法我以前知道单元格的高度,没有它,应用程序运行得非常快。我正在考虑如何改变这种方法以更快地工作......
非常感谢马库斯,真的!
【问题讨论】:
-
我想如果你在主线程中初始化你的 NSManagedObjectContext,你应该只在主线程中使用它。 Prove
-
-updateMessageList从后台线程调用,然后NSManagedObjectContext在那里初始化。代码是正确的,尽管现在已经过时了。