Caching images in tableview - Beginner - iphone

I am using ASIHTTPRequest, i have to populate my table with images. So people at forums suggest to cache the image to increase the performance.
I have no clue how to do this. I will be able to do this if someone helps me with some sample code or give me a link to a tutorial that explains this well. Help
You might think this is duplicate, in fact i too found many similar questions of SO, like this, but none of these helped.

Basically, you keep a dictionary with keys being the cell # and it's object being image. Right when you are about to make a request for an image, first check if it already exists in your dictionary. If it does, simply use that, otherwise, download the image and stick it inside your dictionary.

Simply keep an array of objects that contain all of the information that you want to be shown in the table view. This array can contain objects that hold all of the information that you may need, such as pictures, whether or not the picture has been loaded, labels. Really anything you want. Just make sure that once you are done with the array though that it does get released, which is not much of an issue in iOS 5, but if you are using anything older than that, be sure to release it or at least set the array to nil after.

Related

Saving images then displaying them in a table

Can anyone point me towards an example or tutorial for this? I basically want to save images to the documents folder then have a table that contains them for user review later on.
I've got it working but only when I go and add each image to an array then generate the table with contents of said array first. Is there a quicker or more automated way to do this?
Here's a nice tutorial giving a project you could adapt:
http://www.raywenderlich.com/19788/how-to-use-nsoperations-and-nsoperationqueues
While it's actually about doing lazy loading and other image operations on a secondary thread (keeping your UI responsive) you may as well display images in a table this way to begin with.
The main modification you would make is to look for the locally stored image first, then go and do the network fetch if it is not available. A further refinement would be to check a timestamp stored with each local image and update from the web if a newer one was available.
That is correct, you prepare your datasource first (which is array of images), then you pass it to tableview and reload it. If you are working with lots of images, consider lazy loading.
Apple has an example on this.

iPhone : UITableView reloadData timing problem

I'm encountering a common TableView data reloading problem. I've read many questions on the same subject but the problem was never exactly the same as mine...
I have a navigation based application. In the RootViewController's viewDidLoad method I make a request in order to get JSON data (articles). When the connection has finished loading I create custom Article objects for each entry. The Article class has an initWithDictionnary method which initializes the attributes of the object and most importantly creates a request to download an image. When the connection has finished loading I set the image attribute of the Article object.
The goal is to initialize the cell.imageView.image property with the downloaded image. At that point, you may have guessed what the problem is about.
Images are downloaded after the cell image is rendered so it stays empty until the cell is reloaded (if it gets out of the screen and then back in for example).
I guess I should call reloadData at a certain time but I don't know when. Ideally I would call it when all the cells are loaded but it doesn't seem possible.
I've tried a bunch of crazy things like waiting for a cell to load and the try to reload the previous one but it didn't work.
By reading Q&A out here I learned about Apple's LazyTableImage sample code but I don't understand all of it so I'm not sure I should/could use it.
Please ask me if you need more details.
Thanks in advance for any help.
You have to load the images Asynchronously. Keep in mind that your table data should contain a field per row specifying if the image was loaded so that (if true) you can skip loading and just display cached images.
Look at this question first: Load images async
There are about 10 good Lazy Loading Image UITableView tutorials. Pick one.
You'll get the hang of it by reviewing the tutorials after a while. Stick with it, it's an important concept, not only for this project, but for the rest of your programming career.
Lazy Loading Image UITableView Tutorials that'll make you smarter!

deleting image heavy custom uitableviewcells

I have a table which is made from custom UITableViewCells which contains downloaded images.
Ive found the app crashes after too many images are displayed. How can best stop this? I don't mind deleting the first images, but don't know of the best way to do it.
EDIT
How do I write the images to the device for caching?
Post your cellForRowAtIndexPath code. Sounds like you have a problem there. If you're certain you do not, then when you receive the memory warning, release any objects you do not need, and can easily be loaded again if required. These objects may be in other ViewControllers not on screen or ImageView objects already displayed.
Best we can do unless you post code.
Or read Apple's Memory Management Guide.

Should I be fetching my Core Data more often?

So right now when my app starts I get all of my data from Core Data. My data has entities of Groups and People. The Groups contain People. So as I go through the app I'm adding and deleting People and Groups.
My problem lies when I select a Group from a tableview and I pass that Group onto the next tableview. From that tableview I can press a button/row and add a bunch of People from a modal view. When I press Done from that modal view I need it to update the previous view with those new People, which it's not doing correctly.
It seems a little, for lack of a better word, wrong that I'm passing a lot of stuff around. Would it be better for me to use another fetch after I update People in a Group? From reading what other people say, then I could have different views listen for an updated Core Data and change their views accordingly.
I really hope this makes sense. I've been reading a lot to try to figure out the best approach but I'm not getting anything definite. I feel like my code is turning into spaghetti so I stopped and I'm trying to rethink it all. I'm also thinking maybe I need my very own Model class as opposed to just the classes that Core Data auto-generates.
From what you've written what you're doing sounds about right. I assume you're using a NSFetchedResultsController. Have you implemented the delegate methods outlined in the docs? Specifically, the controllerWillChangeContent: method should give you what you're after.
Regarding implementing your own NSManagedObject subclass, take a look at MOGenerator.
I would recommend NSFetchedResultsController to you. See documentation at ...
http://developer.apple.com/library/ios/#documentation/CoreData/Reference/NSFetchedResultsController_Class/Reference/Reference.html
Look at CoreDataBooks example, especially at RootViewController.m at ...
http://developer.apple.com/library/ios/#samplecode/CoreDataBooks/Listings/Classes_RootViewController_m.html%23//apple_ref/doc/uid/DTS40008405-Classes_RootViewController_m-DontLinkElementID_14
NSFetchedResultsControllerDelegate can help you to update your previous view easily. As I wrote, look at sample code to see how it really works.

Testing if Cocoa object references are valid?

I'm doing some lazy image loading for thumbnails to be displayed in a table. I have a class that loads the image for me asynchronously...but my problem (or at least, a problem) is that by the time the image loads, I have no idea whether the cell that initiated the image load even exists anymore. Is there a way for me to test to see if a particular object reference is valid before I call it?
Thanks.
Not easily or reliably. This is really more of a design problem on your part which could conceivably have many different solutions. My first inclination would be to give the loader some sort of index or hash value rather than a pointer to a live object and tell it to go find the right cell when it's done.