2011-05-26 80 views
2

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

现在,这一切都完美的作品。但我有一个问题:如何更新表视图中的数据?我尝试通过performSelectorOnMainThread:尝试呼叫reloadData,但这会导致竞争条件:reloadData调用有时在窗口关闭命令之后在主线程上排队,并且在窗口关闭后执行,并且所有事情都以火焰进行。

什么是控制和沟通后台线程的最佳方式?

回答

3

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

我的建议是,而不是从你的线程中调用[tableView reloadData],只是信号控制器(通过调用的方法controllerShouldReloadTable),让你的控制器做检查,如果windowWillClose被称为与否。有可能你的控制器在controllerShouldReloadTable的时候也被释放了,为了解决这个问题,你肯定需要从辅助线程中获得retain控制器。

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

最重要的是:我会使用异步调用和一个委托类,以便整个多线程问题可以在其根部解决。

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

+0

这是一个好主意,我会试试这个。但是我不能使用'viewDidUnload',因为它只能在iOS上使用,而在Cocoa中,窗口不是视图。我不认为我需要保留控制器,因为'performSelector'方法仍然保留目标。你能详细说明你的意思是“异步调用和委托类”吗?我不确定我是否明白这一点。 – 2011-05-26 20:06:00

+0

我尝试过了,现在看起来可行。如果线程编程只是不那么难... – 2011-05-26 20:51:33

+0

Jakob,看我的编辑..你会喜欢异步I/O,它是如此自然的事件循环系统... – sergio 2011-05-26 21:42:36