在`viewDidDisappear`上停止`performSelector`启动子线程

时间:2014-01-25 16:44:01

标签: ios objective-c multithreading

首先,我意识到我可能通过错误地解决以前的问题而导致此问题......

ViewController主线程中,我开始使用后台线程从服务器获取更新数据:

[self performSelectorInBackground:@selector(sampleTask:) withObject:@"CMD" ];

此过程可能需要15-30秒,因此在主线程中,我显示SQLite数据库中的数据的本地缓存(从上次打开视图时从上一个请求填充到服务器)并重新加载一次表与服务器的同步完成。

如果用户在与服务器同步完成之前导航回此视图,则后台线程将一直运行直到完成。这本身不是问题,直到用户改变主意并再次回到此视图。如果时机正确,则有两个后台线程尝试与服务器同步数据。如果用户执行此操作几次,则线程计数可能会增加。最终应用程序将崩溃,如果不会导致设备上出现其他问题。

  • 有没有办法在像viewDidDisappear
  • 这样的触发器上停止创建的线程
  • 或者我应该为共享资源(例如NSUserDefaults)写一个锁来阻止新的后台线程被启动?

  • 或者 - 就像我在第一行中提到的那样 - 我是否对更新本地缓存的问题有一个糟糕的方法,这个问题只会导致像这样的问题?

2 个答案:

答案 0 :(得分:1)

我认为你可以使用简单的bool值信号量,它表明某些同步任务正在执行。因此,在执行下一个类似任务之前,您应该检查该信号量。 如果每次需要视图控制器的所有实例都使用静态类变量时重新创建viewcontroller。

答案 1 :(得分:1)

performSelector:withObject:afterDelay:不创建单独的线程。

引用该方法的部分文档:

  

使用。在当前线程上调用接收器的方法   延迟后的默认模式

它会在延迟后使用计时器触发选择器。因此,它与NSTimer具有相同的精度限制。 (方法performSelectorInBackground:withObject: 在后台线程上提交您的选择器。)

但回到你的问题。

您可以使用方法

cancelPreviousPerformRequestsWithTarget:selector:object:

取消对performSelector:withObject:afterDelay:

的待处理通话