Milad
Milad

Reputation: 1269

Receive memory warning and memory leak

I'm using ARC (automatic reference counting).

Is it ok if I set the IBOutlets to nil in the viewDidDisappear instead of viewDidUnload?

Such as these:

[self setTheImage:nil];
[self setBTNplay:nil];
[self setBTNstop:nil];

I'm writing a navigation based app which includes pageViewController, I tested my app in Instruments to see the memory leaks and I keep getting receive memory warning message. I've even put a log code in the viewDidUnload method. But it doesn't seem to get called when I even pop to rootViewController!

One more thing: If each page has an audioPlayer, where should I set a @property (nonatomic, strong) AVAudioPlayer *audioPlayer; to nil?

Or how do I set it to weak instead of strong? Because it gives me a 'warning' then in this code line:

_audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:poemURL error:nil];

it says: Assigning retained object to weak variable

Upvotes: 0

Views: 2685

Answers (4)

user102008
user102008

Reputation: 31323

Is it ok if I set the IBOutlets to nil in the viewDidDisappear instead of viewDidUnload?

There are many things wrong from this statement.

First of all, you do not set IBOutlets to nil in viewDidDisappear. viewDidDisappear is called when the view "disappears" (e.g. when it's in a tab bar controller, and you switch to another tab; or it's on a navigation controller, and you push something on top of it); the view can then "appear" again without loading again. If you set IBOutlets to nil, they will not be set again when you appear. (They are only set when the view is loaded.)

Second, if you have a leak, and setting stuff to nil "fixes it", that means you are not releasing the instance variables. You must always release retained instance variables in dealloc.

I've even put a log code in the viewDidUnload method. But it doesn't seem to get called when I even pop to rootViewController!

Yes, viewDidUnload is only called in low memory situations. It is not called normally in most situations. If you were depending for it to be called, you were using the wrong method.

Upvotes: 0

nsinvocation
nsinvocation

Reputation: 7637

First, do not set to nil your properties in viewDidDisappear cause your view is still loaded. You must always set them to nil in viewDidUnload. It's invoked in low memory situations and here you must clean-up all stuff that breaks system memory.

Apple's UIViewController reference for viewDidUnload

When a low-memory condition occurs and the current view controller’s views are not needed, the system may opt to remove those views from memory. This method is called after the view controller’s view has been released and is your chance to perform any final cleanup.

Second , take a look at this tutorial where is explained very well ARC

Upvotes: 2

Jesse Rusak
Jesse Rusak

Reputation: 57178

Are you calling [[NSNotificationCenter defaultCenter] removeObserver:self]; from one of your view controller subclasses? If so, that would explain why you're not getting viewDidUnload called.

If that's the problem, you should remove yourself from specific notifications when needed rather than all notifications as above. (It's OK to call removeObserver:self from dealloc, though.)

Upvotes: 0

Jack Lawrence
Jack Lawrence

Reputation: 10782

You don't need to nil out those values in viewDidUnload. Make sure you're using weak properties instead of strong or assign for IBOutlets. Received memory warning doesn't necessarily mean you're leaking. Received memory warning means that your app is consuming too much memory. Run Instruments and edit your question with how much memory your app uses.

The fact that you're using AVAudioPlayer makes me thing that maybe you're pulling down some massive audio files into memory.

Also by the way, initWithContentsOfURL:error: will get you rejected from the App Store because you're blocking the main thread. Try testing your app on an iPhone with only cellular enabled and go into a part of your office/house that has a bad internet connection. Also try with your phone switched to airplane mode. Your app will undoubtedly either freeze for a long time before the connection fails or it will simply crash.

Instead, you should be using grand central dispatch or downloading it via NSURLConnection's block or delegate methods.

Upvotes: 2

Related Questions