我有一个NSOperation,我把它放入队列。 NSOperation执行一些长时间的照片处理,然后将信息/元数据保存在该照片的核心数据中。在我的自定义NSOperation类的主要方法中,我执行下面的代码块
-(void)main
{
//CODE ABOVE HANDLES PHOTO PROCESSING...
//........
//THEN I SAVE ALL DATA BELOW LIKE SO
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
Post *post = [Post createInContext:localContext];
//set about 15 pieces of data, all strings and floats
post.XXXX = XXXXX;
post.DDDD = DDDDD;
etc...
} completion:^(BOOL success, NSError *error) {
NSLog(@"Done saving");
}];
}
我的问题是,即使只保存3张照片,它也会冻结我的用户界面。我本以为在NSOperation中执行这个我会没事的。
我应该补充一点,每个NSOperation处理一张照片,所以有时队列可能有5-10张照片,但我不认为这会有任何区别,即使只有三个像我说它冻结UI。
感谢您的帮助。
UPDATE:------------的 * --------------
我切换到2.2版但是这似乎阻止了UI更多......现在我正在使用
-(void)main
{
NSManagedObjectContext *localContext = [NSManagedObjectContext contextForCurrentThread];
//CODE BELOW HANDLES PHOTO PROCESSING...
//........
//THEN I SAVE ALL DATA BELOW LIKE SO
Post *post = [Post createInContext:localContext];
//set about 15 pieces of data, all strings and floats
post.XXXX = XXXXX;
post.DDDD = DDDDD;
[localContext saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
}];
}
这一切都是在我的NSOperation课程中完成的,我做错了吗?
答案 0 :(得分:10)
不要将saveWithBlock调用放在后台线程中。您正在从后台线程中有效地创建后台线程,在这种情况下,这只会减慢您的速度。您应该只能调用saveWithBlock,它应该将所有保存代码放在后台。但是,我还注意到您在代码的主UI页面中进行了所有更改,之后只调用save。这是此方法的错误用法。你想做更像这样的事情:
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
Post *post = [Post createInContext:localContext];
//photo processing
//update post from photo processing
} completion:^(BOOL success, NSError *error) {
//This is called when data is in the store, and is called on the main thread
}];
如果你确实需要NSOperation,我建议采用不同的模式:
- (void) main {
NSManagedObjectContext *localContext = [NSManagedObjectContext confinementContext];
// Do your photo stuff here
Post *post = [Post createInContext:localContext];
//more stuff to update post object
[localContext saveToPersistentStoreAndWait];
}
答案 1 :(得分:0)
小心如何开始操作。
[operation start]
将在当前线程上启动操作,因此如果从主线程(即UI线程)调用它,它将阻止该接口。
您应该将操作添加到队列中,以便它在后台运行而不会占用主线程
[[NSOperationQueue new] addOperation:operation];