5

我正在分离一个线程在后台做一些操作,参考下面的代码

 currentThread = [[NSThread   alloc]initWithTarget:contactServiceselector:@selector(requestForContactBackup:)object:msisdn];

 [currentThread start];

这个 currentThread 是 AppDelegate 中声明的指针。我的视图上有一个按钮,点击它,后台线程的执行应该停止。参考以下代码:

-(void)cancelTheRunningTasks {
    
   if(self.currentThread !=nil) {

        [currentThread cancel];
        NSLog(@"IsCancelled: %d",[currentThread isCancelled]);   //here Yes returns
        [self removeNetworkIndicatorInView:backUpViewController.view];
    }  
}

以下代码的问题是后台线程仍在执行中。

我的问题是,有线程引用,如何从主线程取消/停止执行/杀死后台线程?

请建议我可能的解决方案。谢谢。

4

3 回答 3

4

您的后台线程需要检查它是否已被取消,或者通过isCancelled方法...

if ([[NSThread currentThread] isCancelled]) {
    // do cleanup here
    [NSThread exit];
}

您不能从外部杀死线程,因为无法知道线程可能处于什么状态,因此,杀死它会产生不确定的行为(想象一下,如果线程在被杀死时在分配器中保持互斥锁。 ..哎哟)。

于 2013-03-14T16:18:51.000 回答
3

cancel
更改接收器的取消状态以指示它应该退出。

exit
终止当前线程。

检查NSThread 类参考

有关取消和操作对象的更多信息,请参阅NSOperation 类参考

注意:在 OS X v10.6 中,cancel 方法的行为取决于操作当前是否在操作队列中。对于未排队的操作,此方法将操作标记为立即完成,生成适当的 KVO 通知。对于排队操作,它只是将操作标记为准备好执行并让队列调用它的 start 方法,该方法随后退出并导致从队列中清除操作。

于 2013-03-14T16:07:07.753 回答
3

我解决了问题。正是我想要做的就是我想从我的主线程或其他线程中停止或终止某些后台线程的工作条件。当我阅读Apple文档和一些帖子时,我得出结论,我们不能从另一个线程中杀死一个线程,因为它们所有线程共享公共内存空间和资源,并且由另一个线程杀死线程并不是更好(但是一个进程可以杀死另一个进程,因为两个进程之间没有公共内存空间共享)。然后我得到信息,我们不能像那样退出/杀死线程,但我们仍然可以从其他线程设置正在运行的线程的取消属性。(在用户请求取消任务的代码中)。

所以在这里我们可以设置取消属性。在我们正在执行的后台任务代码中,只需检查是否设置了取消属性。(我们需要在一段代码执行后进行监控)。如果设置了取消属性/是,则在该后台线程代码中调用 [Thread exit] 并释放该线程分配的所有内存以保护内存泄漏(此处自动释放池不会释放资源)。

这就是我解决问题的方法。

简单——>只需将您要取消的特定任务的属性设置为取消集。(设置取消的方法将由线程对象引用调用)。

 if(self.currentThread != nil && [currentThread isExecuting])
   {
      [currentThread cancel];
   }

然后在您的代码中监视取消属性。如果设置了属性,则退出线程。

if([appDelegate.currentThread isCancelled])
 {
      [NSThread exit];
 }

如果有人有比这更好的解决方案,请参考。否则它也可以正常工作。

于 2013-03-15T10:21:05.077 回答