在后台线程上执行核心数据保存? [英] Executing Core Data saving on a background thread?

查看:96
本文介绍了在后台线程上执行核心数据保存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个按钮,用于将Core Data SQLite中的选定条目标记为收藏夹,这意味着我只是将 BOOL 翻转为该索引



当前,当我这样做时,我在上调用 save 根据Instruments的说法,managedObjectContext 可能需要500毫秒,或者可能要多一些。



我有一些同时执行的代码会触发一次小小的粒子爆炸(万岁,最喜欢的!),但是我遇到了一个问题,该爆炸被延迟到保存完成之后。



我不确定为什么,因为触发爆炸的代码在 save 调用之前。我是一个相对较新的程序员,所以也许我错过了一些东西,但是在这种情况下代码不是逐行执行的,因为爆炸会触发,然后保存就会进行?在这里的委托调用可能也需要一些时间,但是同样的问题也适用,如果在这些代码行之后,为什么会很重要?



编辑:我是说对了,因为在下一行代码出现粒子之前,主线程已被阻塞,这意味着UI无法自我更新?



这是我的代码:

  //粒子动画
LikeExplosion * likeExplosionView = [[LikeExplosion alloc] initWithFrame:CGRectMake(0 ,0、320、400)];
[likeExplosionView setUserInteractionEnabled:NO];
[self.view addSubview:likeExplosionView];
[self.view BringSubviewToFront:likeExplosionView];
[likeExplosionView fadeOverTime:1.1];

//委托调用以在其他位置重新加载tableview
[self.delegate detailViewControllerDidLikeLine];

//更新当前对象
[_selectedLine setIsLiked:[NSNumber numberWithBool:YES]];
[_selectedLine setIsDisliked:[NSNumber numberWithBool:NO]];

//更新上下文
NSError * error;
if(![[[[[CDManager sharedManager] managedObjectContext] save:& error])NSLog(@保存更改失败:%@,%@,error,[error userInfo]);

第一个问题:为什么我第一次调用动画代码时会有延迟



第二个问题:是否会将 save 调用放在背景上线程可以解决问题,这样做是否安全/一个好主意?

解决方案

动画,通常与UI相关的所有操作均在主线程上执行。如果您不想持久化磁盘(保存过程)来保持UI(主线程),则需要通过 NSManagedObjectContext 将上下文放入其自己的专用队列中的 initWithConcurrencyType:方法。专用队列将为您处理与上下文有关的所有后台线程。三种类型为:

  NSConfinementConcurrencyType 
NSPrivateQueueConcurrencyType
NSMainQueueConcurrencyType

您需要 NSPrivateQueueConcurrencyType



您可以通过使用具有不同并发类型的子/嵌套管理对象上下文来采用更复杂的体系结构路线,但是如果您是Core Data的新手,请坚持使用单个上下文,直到您牢牢掌握上下文和队列为止。


I've got a button which marks a selected entry in a Core Data SQLite as a "Favourite", meaning I'm just flipping a BOOL for that index from off to on.

Currently, when I do this, I call save on the managedObjectContext, which takes maybe 500ms, perhaps a little more, according to Instruments.

I have some code that executes at the same time which triggers a nifty little particle explosion ("Hooray, a favourite!"), but I'm running into an issue where that explosion is delayed until after the save has completed.

I'm not sure why, since the code to trigger the explosion is before the save call. I'm a relatively new programmer so perhaps I'm missing something, but doesn't code execute line by line in a case like this, in that the explosion would trigger, then the save would occur while it's going? The delegate call here may be taking some time too, but the same question applies, why would it matter if it's after those lines of code?

EDIT: Am I right in saying that the main thread is being blocked before the particles appear by the next lines of code, meaning the UI can't update itself?

Here's my code:

// Particle animation
LikeExplosion *likeExplosionView = [[LikeExplosion alloc] initWithFrame: CGRectMake(0, 0, 320, 400)];
[likeExplosionView setUserInteractionEnabled: NO];
[self.view addSubview: likeExplosionView];
[self.view bringSubviewToFront: likeExplosionView];
[likeExplosionView decayOverTime: 1.1];

// Delegate call to reload tableview elsewhere
[self.delegate detailViewControllerDidLikeLine];

// Update current object
[_selectedLine setIsLiked: [NSNumber numberWithBool: YES]];
[_selectedLine setIsDisliked: [NSNumber numberWithBool: NO]];

// Update context
NSError *error;
if (![[[CDManager sharedManager] managedObjectContext] save:&error]) NSLog(@"Saving changes failed: %@, %@", error, [error userInfo]);

First question: why is there a delay, when I'm calling the animation code first in the method?

Second question: would putting the save call on a background thread solve the problem, and is it safe / a good idea to do so?

解决方案

Animations, and generally anything have to do with the UI is executed on the main thread. If you don't want the persistence to disk (the saving process) to hold up your UI (main thread) you need to put the context on it own private queue via NSManagedObjectContext's initWithConcurrencyType: method. The private queue will handle any background threads having to do with the context for you. The three types are:

NSConfinementConcurrencyType
NSPrivateQueueConcurrencyType
NSMainQueueConcurrencyType      

You would want NSPrivateQueueConcurrencyType.

You could take a more complex architecture route by using child/nested managed object contexts with different concurrency types, but if you are new to Core Data, stick with a single context until you get a firm grasp of contexts and queues.

这篇关于在后台线程上执行核心数据保存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆