收到內存警告和內存洩漏 (Receive memory warning and memory leak)


問題描述

收到內存警告和內存洩漏 (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

‑‑‑‑‑

參考解法

方法 1:

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.

方法 2:

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 

方法 3:

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.)  

方法 4:

  

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 viewDidDisappearviewDidDisappear 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.

(by MiladJack LawrencensinvocationJesse Rusakuser102008)

參考文件

  1. Receive memory warning and memory leak (CC BY‑SA 3.0/4.0)

#iboutlet #didreceivememorywarning #iOS #uipageviewcontroller






相關問題

iOS - IB 視圖模式 (iOS - IB view mode)

NSWindow 的 IBOutlet 組件什麼時候初始化? (When IBOutlet components of NSWindow are initialized?)

收到內存警告和內存洩漏 (Receive memory warning and memory leak)

如何在 init 方法中從 NIB 加載 IBOutlets? (How to load the IBOutlets from NIB in the the init method?)

將 xib 從一個項目複製到另一個項目 (copy the xib from one project to another project)

將案例編碼到 appDelegate 文件中 (The case(s) coding into appDelegate file)

nib 中的 UIView 在 iPad 上是 nil,在 iPhone 上不是 nil (UIView in nib is nil on iPad, and not nil on iPhone)

awakeFromNib 無法從 UILabel 獲取值,也無法禁用 UIButton (awakeFromNib can't get value from UILabel and can't disable UIButton)

“找不到名為 ViewController 的類的任何信息” ("Could not find any information for class named ViewController")

在 Xcode 7 中將出口從文件連接到情節提要 (Connect outlet from file to storyboard in Xcode 7)

為什麼“文件所有者”有時會有“視圖”出口?我可以添加我自己的嗎? (Why does "File's Owner" sometimes have a "view" outlet? Can I add my own?)

Interface Builder 中的 IBOutletCollection 集排序 (IBOutletCollection set ordering in Interface Builder)







留言討論