I have a custom UITableViewCell, and when the user clicks a button i make a request to a server and update the cell. I do this with a NSUrlConnection and it all works fine (this is all done inside the cell class) and once it returns it fires a delegate method and the tableivew controller handles this. However when i create the cell in the tableview, i use the dequeue method and reuse my cells. So if a cell has fired a asynchronous nsurlconnection, and the cell gets reused whilst this is still going on, will this in turn erase the current connection? I just want to make sure that if the cell is reused, the actual memory that was assigned to the cell is still there so the connection can fulfil its duty??
2 Answers
You can customize the behavior of a UITableViewCell
by subclassing it and overriding the -perpareForReuse
method. In this case, I would recommend destroying the connection when the cell is dequeued. If the connection should still keep going, you’ll need to remove the reference to it (set it to nil
) and handle its delegate methods elsewhere.

- 19,021
- 6
- 70
- 80
It's never a good idea to keep a reference of a connection or any data that you want to display in a cell, no matter how much of effort you put into it afterward to work around to arising problems. Your approach will never work reliable.
In your case, if the user quickly scrolls the table view up and down, your app will start and possibly cancel dozens of connections and yet never finishes to load something. That will be an awful user experience, and may crash the app.
Better you design your app with MVC in mind: the cell is just a means to display your model data, nothing else. It's the View in this architectural design.
For that purpose the Table View Delegate needs to retrieve the Model's properties which shall to be displayed for a certain row and setup the cell. The model encapsulates the network connection. The Controller will take the role to manage and update change notification and process user inputs.
A couple of Apple samples provide much more details about this topic, and there is a nice introduction about MVC, please go figure! ;)
http://developer.apple.com/library/ios/#documentation/general/conceptual/devpedia-cocoacore/MVC.html
The "Your Second iOS App: Storyboards" also has a step by step explanation to create "Data Controller Classes". Quite useful!
Now, when using NSURLConnection which updates your model, it might become a bit more complex. You are dealing with "lazy initializing models". That is, they may provide some "placeholder" data when the controller accesses the property instead of the "real" data when is not yet available. The model however, starts a network request to load it. When it is eventually loaded, the model must somehow notify the Table View Controller. The tricky part here is to not mess with synchronization issues between model and table view. The model's properties must be updated on the main thread, and while this happens, it must be guaranteed that the table view will not access the model's properties. There are a few samples which demonstrate a few techniques to accomplish this.

- 18,174
- 3
- 45
- 67
-
Ok thanks for the info! If I make an asynchronous nsurlconnection, when the didFinishLoading method is called, will what ever I write In this method be called in the main thread or will it still be in the separate thread?? – Tyler Durden May 26 '13 at 08:33
-
The delegate methods will be executed on the thread where the connection has been scheduled. Usually, a connection will be scheduled on a run loop, but there is a 1:1 relation between a thread and a run loop. (you can also schedule a connection on an NSOperationQueue - you'll find more on that topic in the docs). From within the delegate methods you can dispatch to any other queue, for instance to the main queue whose blocks/operations will be executed on the main thread. – CouchDeveloper May 26 '13 at 09:21
-
ok thanks a lot for the info. If i want to dispatch some code back to the main thread, am i correct in using dispatch_async(dispatch_get_main_queue(), ^{ // do work here }); – Tyler Durden May 26 '13 at 16:52
-
Yes, this is correct. Alternatively, you might use performSelector* family methods to schedule a method to another thread (including the main thread). I would suggest to use dispatch lib and queues unless you need a feature you only get with performSelector*. – CouchDeveloper May 27 '13 at 09:44