0

I have a navigation based app. The screen List has a UITableView with a list of books. The list of books is in a property NSArray that was built dynamically by executing an HTTP request. When one clicks in one of the rows in the List, one'll navigate to the screen Details. Let's say there is a memory warning at this point. When you come back to the screen List, the NSArray is nil because viewDidUnload was called, so the List will be empty.

What is the correct way to handle this situation? Should I not set the NSArray to nil in viewDidUnload?

Adriana
  • 806
  • 11
  • 36

4 Answers4

1

Typically you will only nil out properties for your IBOutlet UI elements. You can also safely clean up anything that you can recreate in -viewDidLoad. But generally speaking, this method is only for cleaning up and freeing memory related to the view, not the view controller.

Seamus Campbell
  • 17,816
  • 3
  • 52
  • 60
  • So, the short answer is that I shouldn't set the NSArray to nil, right? Does this mean the NSArray will only be released when the app finishes? – Adriana Jul 31 '11 at 18:22
  • Correct on the first question. The array will be released when the view controller is destroyed (presuming you've released it in `-dealloc`). If the view controller is always in the navigation controller's stack, then the array will survive until the app finishes. – Seamus Campbell Jul 31 '11 at 18:52
  • I'm calling `[super dealloc]` in the `-(void)dealloc` method of my UIViewController's subclass, so the view controller is destroyed, right? Last question: I shouldn't define the `-(void)dealloc` method in my models, right? Otherwise the data will be lost in case there is a memory warning, I guess... Thank you for the clear clarifications :) – Adriana Jul 31 '11 at 19:18
  • Any time you have retained ivars in your object you will need to write a `-dealloc` method to release them when your object is destroyed. That method should call `release` on each retained object and should also call `[super dealloc]`. – Seamus Campbell Jul 31 '11 at 19:21
0

The correct way is not to store your data in a UIViewController, but in another object that manages your data.

A viewcontroller serves as a link between your model and your screen. You should not use it to store your data.

Joris Mans
  • 6,024
  • 6
  • 42
  • 69
  • I'm not sure this is relevant advice -- wherever the data is "stored", you need at least a reference to it in the view controller. For transient data that isn't persisted, the data is stored on the heap. Adriana doesn't specify if a model class was used to abstract the fetch or if it was performed in the model class. – Seamus Campbell Jul 31 '11 at 18:04
  • The way the question is asked (and the fact it is) just gives me a gut feeling that the data is fetched and stored inside the viewcontroller. I encounter this kind of code quite regularly. Call it an educated guess ;) – Joris Mans Jul 31 '11 at 18:07
  • Even if it is, it doesn't address the question that is being asked. – Seamus Campbell Jul 31 '11 at 18:09
  • I'm using a modal. I just wanted to simplify the question. – Adriana Jul 31 '11 at 18:23
0

Usually I set NS(Mutable)Array of the objects in void dealloc(). Nil and release (if the object is not autoreleased).

If you use uinavigationcontroller, the view is pushed, so when you return from your detail view, normally you will have your previous data, unless you put in viewwillappear a refresh.

My guess is that you have a problem freeing the memory from the http request.

Panagiotis
  • 1,539
  • 1
  • 14
  • 28
0

If you array is built in the viewDidLoad section then you can set it to nil. When the view is recalled it will be rebuilt.

Generally you want to set anything to nil in the viewDidUnload that can be rebuilt in either the viewDidLoad section or the xib file.

I would recommend initializing lazily though like this -

- (NSArray *)bookArray {
    if (bookArray == nil) {
        bookArray = [[NSArray alloc] init];
    }
    return bookArray;
}

then in the viewDidLoad:

self.bookArray = [NSArray arrayWithOjects:...,nil];
Dmorneault
  • 199
  • 1
  • 8