I have a window that displays some data in an NSTableView. This data is loaded in the background. The data-loading-thread is started in the windowDidLoad: method. If the window is closed before loading has finished, the background thread should be cancelled. I do this by signalling the thread in the windowWillClose: delegate method and waiting for the background thread to finish.
Now this all works perfectly. But I have one problem: How can I update the data in the table view? I have tried calling reloadData via performSelectorOnMainThread: but this leads to a race condition: The reloadData call is sometimes queued on the main thread after the window close command, and will execute after the window has closed, and everything goes up in flames.
What’s the best way to control and communicate with a background thread?
Well, you know, this is exactly what makes the use of threading complex: you always face synchronization issues.
What I suggest is, instead of calling
[tableView reloadData]from your thread, simply signal your controller (by calling a methodcontrollerShouldReloadTable) and let your controller do the check ifwindowWillClosehas been called or not. There might be a chance that your controller has been also released by the timecontrollerShouldReloadTable, and to fix this you will definitely need toretainthe controller from the secondary thread.On a side note, I would cancel the thread in
viewDidUnload(for symmetry).Most important: I would use asynchronous calls and a delegate class so that the whole multithreading issue is solved at its root.
EDIT: Sending asynchronously a request will not block the sending thread waiting for the response. Instead, asynchronous send (for
NSURLConnectionis calledstart) immediately returns (so, no blocking) and when the response is received, a delegate method will be called (i.e.,connectionDidFinishLoading:) so that you can updated the model and the UI. Take a look atNSURLConnectiondocs, but as usual, I strongly suggest using[ASIHTTPRequest][2], which has many advantages.