UITableView's cells release when not visible - iphone

I have a UITableView. each row is heavy object with videos, images etc.
When user scrolls this view how can I release the memory of not visible rows and load the current visible rows?

I assume you're talking about releasing memory that's used by the images and videos of your row, and not the row itself.
In your tableview delegate,
-(void) scrollViewDidEndDecelerating:(UIScrollView *)scrollView
tells you when the tableview scrolling has stopped.
[myTableView indexPathsForVisibleRows]
gives you an array of what is visible.
If your row is not in this array, it is not visible, and you can do your image/video cleanup on it.

Are you recycling UITableViewCells as per Apple's recommendations? If not, you MUST read Apple's docs. Inside the cellForRowAtIndexPath: delegate you should have something [customCell setMediaObjects:]. Inside your customCell class you can release all the previous mediaObjects from memory.

As others have said, you should make sure you are recycling cells properly, and not destroying things you would need to recreate anyway when the cell is reused.
But, you may want to release other assets that the cell or its views are retaining. Or if that cell has any pending download requests, for example, you may want to reset their priority or even cancel them when the cell is offscreen.
I think the cleanest way to do this is to just override -[UITableViewCell prepareForReuse]
This is called when the cell is put back into the reuse queue. If the user is moving up and down the table quickly, you may not want to clean the cell up the moment the cell is off the screen (by looking at indexPathsForVisibleRows, for example).
But when the cell is actually put back in the reuse queue, that is a good time to do that work since you know that cell won't appear again on screen until you dequeue and configure it again.

A Closer Look at Table-View Cells - Apple Documentation
When you call dequeueReusableCellWithIdentifier first 10 (just ten cells can be shown at screen at one moment) cells will be created, then they will be just loaded and configured for showing.
So, cells are not released.

Related

iPad UITableView flickering issue

I have a UITableView that contain about 20 rows in the iPad's viewport. I have a interval timer that will call UITableView's reloadData regularly(post it to UI thread).
Now when I scroll through the UITableView with medium speed (not so fast), that UITableView will refresh with flickering effect.
I have to write a function to manually update the UITableViewCell label by looping through all the items in the array (this array keep all the items that show on UITableView). I will execute this function when timer is running instead of calling reloadData (as I mentioned above). Then the flickering issue is gone.
I believe that reloadData should be better than looping through all the data because reloadData will only refresh the current showing Cells instead of all the rows, but I couldn't figure out why the flickering happens. Anyone know why?
One thing I have to mention is I did use the CellIdentifier correctly to reuse the cell and only create the cell when the retrieved cell is null.
Moreover, I do not have this issue in iPhone and I believe that it is because iPhone has lesser row compare to iPad.
Anyone can give some explanation about this issue?
I had the same problem with flickering when using reloadData. I solved it by using indexPathsForVisibleRows and cellForRowAtIndexPath: to only update the visible cells. Performance is good since I don't have to iterate over the whole data set, but only a limited number of visible cells.
reloadData causes the tableview to recreate the visible cells on screen which can result in a flickering since the cells get destroyed. There are better ways to reload the tableview. Are you using Core Data? If so the NSFetchedResultsController and it's delegate are a great way to update a tableview since it listens to changes in the underlying datasource and only updates the appropriate cells.

iphone tableview scrolling issue

I have a tableview with imageviews and textviews in each cell. When my view is loaded one of the textviews is invisible. But when I start scrolling the textview appears, so that my view looks as it is supposed to look. Does anyone know why this is happening?
P.S. I have read about reusing cells when scrolling so I have been very careful to construct my cells correctly.
Without code, no one can give you a exact answer. But for a guess....
Is your data is getting populated after your table call cellForRowAtIndexPath? When the cell populates the first time, no data, so the cell is in it's unformatted state. By the time you can interact with the table and scroll it off and on screen (which calls cellForRowAtIndexPath again), the data has been populated and so the cell looks as expected.
You can test this by putting a breakpoint in your cellForRowAtIndexPath method and check to see if your data objects are initialized or still set to nil.

Threaded thumbnail-loading for imageview in a table cell

I'm looking for suggestions on how to make an efficient thumbnail-loader for navigation-lists in the form of tables. I can start a thread and download and cache the thumbnails, but I'm unsure on how to update a table cell with the image (a cell either visible or outside the view).
I think the app Blocket does what I'm after, if I remember correctly.
I'd like to set a placeholder image, and as the thread loads each image, it updates the cells. The placeholder could be an animated activity indicator (spinner), if possible.
Are there any terse example-code out there, or can you give suggestions on how to communicate the update to the cell and force it to display the image immediately?
Interesting problem.
I guess at some level you'll need to replace the existing cells in the table view via the reloadRowsAtIndexPaths:withRowAnimation: UITableView method, so I suspect you'll need to keep a lookup of cell contents -> indexPaths so you know which cells to update when the relevant asset becomes available.
However, you'll need to avoid breaking the existing cell re-use system. (i.e.: there's no value in pre-creating all of the cells in advance.) As such, much of this work should be done within the - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath UITableViewDelegate method, I suspect.
That said, hopefully you'll get a better response than these somewhat vague ramblings. :-)
Made the nicest threaded thumbnail loading I've seen yet on iPhone :D The hardest part was cancelling a thread when navigating away from its table. An NSThread loading images and performSelectorOnMainThread waitUntilDone:YES for when updating the cell.imageView, passing objects (cell, tableView, indexPath etc) in an array to bypass the limitation of passing only one object in withObject. Looks royale with a quick fade-in of each image as they load :)

deleteRowsAtIndexPaths doesn't release the cell?

I have a functionality in my table view i.e. when you tap in on cell it loads more cells in below the tapped cell and when you tap again on same cell those added cells gets deleted.
But I have got a strange behavior that when i call below method to delete added cells from table view, the dealloc method of cell isn't being called..(I have placed a NSLog in dealloc method)
[tableView deleteRowsAtIndexPaths:indexPathArray withRowAnimation:UITableViewRowAnimationTop]
and when I call insertRowsAtIndexPaths then new instance of cells are being created, in the instruments I checked that the previous instances remain in memory and new instances are being created again and again.
so please tell me that why is deleteRowsAtIndexPaths not calling release for deleted cell? and some solution for this problem. I am worried because application's real and virtual both memory consumption is keep increasing on continuous taps...
Do you use UITableView's dequeuereusablecellwithidentifier: method in cellForRowAtIndexPath: in order to create new cells?
If not, this is normal. UITableViews keep cells in memory in order to reuse them and avoid having to alloc/dealloc all the time.
You should take a look at this tutorial for example: http://www.mobisoftinfotech.com/blog/iphone/introduction-to-table-view/

IPhone custom UITableViewCell Reloading

currently I'm struggling with this problem:
I got a UITableViewController that displays a tableView with different custom cells.
One custom cell displays a number (by a label). If you click on this cell, the navigationController moves to a UIPicker where the user can select the number to be displayes.
If the user moves back, the cell should display the updated value.
Problem:
I managed to reload the cells by calling
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.tableView reloadData];
}
in the UITableViewController.
This works only, if I don't use dequeueReusableCellWithIdentifier for the cell (tables won't show updates otherwise).
But in this case, memory usage grows and grows...
In addition, the program crashes after about 15 movements to pickerView and back - I think because the cell that should be reloaded is already released.
How can I update a reusable custom cell every time the view appears ?
What is the best solution ?
I think retaining cells should not be used ?
A general approach is to avoid reloading the whole table if only one cell is changed.
In such case, just get the reference to the UITableViewCell you want to "refresh" and invoke a [self setNeedsDisplay] from the main thread on it to trigger its refresh (will call the drawRect on it to trigger its drawing).
Have you set the appropriate id in the NIB? It has to be the same as you use when calling dequeueReusableCellWithIdentifier:
See step 3 here