在后台线程中可取消加载

时间:2011-05-26 19:00:04

标签: objective-c cocoa thread-safety

我有一个窗口,显示NSTableView中的一些数据。此数据在后台加载。数据加载线程以windowDidLoad:方法启动。如果在加载完成之前关闭窗口,则应取消后台线程。我通过在windowWillClose:委托方法中发信号并等待后台线程完成来完成此操作。

现在一切都很完美。但我有一个问题:如何更新表格视图中的数据?我尝试通过reloadData调用performSelectorOnMainThread:但这会导致竞争条件:reloadData调用有时在窗口关闭命令后在主线程上排队,并在窗口执行后执行关闭,一切都火上浇油。

控制后台线程并与后台线程通信的最佳方法是什么?

1 个答案:

答案 0 :(得分:3)

嗯,你知道,这正是使线程使用变得复杂的原因:你总是面临同步问题。

我的建议是,不是从你的线程中调用[tableView reloadData],而是简单地通知你的控制器(通过调用方法controllerShouldReloadTable)并让你的控制器检查windowWillClose是否已经是否打电话。您的控制器有可能在controllerShouldReloadTable之前被释放,为了解决这个问题,您肯定需要从辅助线程retain控制器。

在旁注中,我会取消viewDidUnload中的线程(对称性)。

最重要的是:我会使用异步调用和委托类,以便从根本上解决整个多线程问题。

编辑:异步发送请求不会阻止发送线程等待响应。相反,异步发送(对于NSURLConnection称为start)立即返回(因此,没有阻塞),并且当收到响应时,将调用委托方法(即connectionDidFinishLoading:)所以您可以更新模型和UI。请查看NSURLConnection个文档,但与往常一样,我强烈建议您使用[ASIHTTPRequest][2],其中many advantages