如何启动 NSRunLoop,并确保它有一个被清空的 NSAutoreleasePool?

发布于 2024-09-01 16:38:15 字数 898 浏览 6 评论 0原文

我有一个“同步”任务,它依赖于多个“子任务”,其中包括异步网络操作,但所有这些都需要访问单个 NSManagedObjectContext 。由于 NSManagedObjectContext 的线程要求,我需要这些子任务中的每一个都在同一线程上执行。由于其中一些任务的处理量很大,我需要将它们放在后台线程上。

目前,我正在通过在单例 SyncEngine 对象的 -init 方法中执行此操作来启动一个新线程:

[self performSelectorInBackground:@selector(initializeSyncThread) withObject:nil];

-initializeSyncThread 方法如下所示this:

- (void)initializeSyncThread
{
    self.syncThread = [NSThread currentThread];
    self.managedObjectContext = [(MyAppDelegate *)[UIApplication sharedApplication].delegate createManagedObjectContext];
    NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
    [runLoop run];
}

这是为此线程启动 NSRunLoop 的正确方法吗?有更好的方法吗?运行循环只需要处理“performSelector”源,并且它(及其线程)应该在进程的生命周期内存在。

在设置 NSAutoreleasePool 时,我是否应该使用 Run Loop Observers 创建自动释放池并在每次运行后耗尽它?

I have a "sync" task that relies on several "sub-tasks", which include asynchronous network operations, but which all require access to a single NSManagedObjectContext. Due to the threading requirements of NSManagedObjectContexts, I need every one of these sub-tasks to execute on the same thread. Due to the amount of processing being done in some of these tasks, I need them to be on a background thread.

At the moment, I'm launching a new thread by doing this in my singleton SyncEngine object's -init method:

[self performSelectorInBackground:@selector(initializeSyncThread) withObject:nil];

The -initializeSyncThread method looks like this:

- (void)initializeSyncThread
{
    self.syncThread = [NSThread currentThread];
    self.managedObjectContext = [(MyAppDelegate *)[UIApplication sharedApplication].delegate createManagedObjectContext];
    NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
    [runLoop run];
}

Is this the correct way to start up the NSRunLoop for this thread? Is there a better way to do it? The run loop only needs to handle 'performSelector' sources, and it (and its thread) should be around for the lifetime of the process.

When it comes to setting up an NSAutoreleasePool, should I do this by using Run Loop Observers to create the autorelease pool and drain it after every run-through?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

转身以后 2024-09-08 16:38:15

我不是 100% 确定这是解决您的问题的最有效方法,但我正在这样做...

由于异步网络操作可能需要不同的时间来完成(或超时),我用以下方式跟踪它们一个实例变量(在本例中是一个名为 callComplete 的 BOOL)

当启动网络请求的代码时,我的 NSURLConnection 已经消失并发挥了魔力,我像这样等待通话完成。

while(!callComplete && [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]){
    // Here you can perform other checks, like making sure the method isn't running forever (with a timeout variable)
    // Just set callComplete to YES when done
}

I'm not 100% sure this is the most efficient way to solve your problem, but I'm doing like this...

Since the asynchronous network operations can take different time to complete (or to timeout) I keep track of them with an instance variable (in this case a BOOL called callComplete)

When the code for firing of the network reqeust is started, and my NSURLConnection has gone away and doing it's magic, I wait for the call to be complete like this.

while(!callComplete && [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]){
    // Here you can perform other checks, like making sure the method isn't running forever (with a timeout variable)
    // Just set callComplete to YES when done
}
野心澎湃 2024-09-08 16:38:15

关于 NSAutoreleasePool,我只是在后台运行的选择器的开头创建一个。然后,在运行循环完成后(并且我的调用完成),我在返回之前像往常一样释放。

Regarding the NSAutoreleasePool, I simply create one on the start of my selector that is run in the background. Then after the Run Loop is done (and my calls are complete) i release as usual before returning.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文