简体   繁体   中英

iOS memory management with ARC

Let's say i'm working on an app with a large number of views and i have some problems understanding memory management when the UIViewController segues to another UIViewController.

Which of the following object should i release in viewDidDisappear: ?

@property (weak, nonatomic) IBOutlet UIImageView *background;

@property (strong,nonatomic) UILabel *playerLevel;

- (void)viewDidLoad
{
    [super viewDidLoad];

    map = [[MapView alloc]init];
    [self.view addSubview:map];
}

Is this the correct way to do this ?

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:YES];

    [_background removeFromSupeview];
    [self.playerLevel removeFromSupeview];
    [map removeFromSupeview];

    _background = nil;
    self.playerLevel = nil;
    map = nil;
}

You don't need to do anything. ARC will implement the dealloc method for you, which will call all releases for your retained properties.

I really recommend you read the memory management documentation from apple, it will help to understand what ARC is really doing, including understanding how retain cycles can be avoided.

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html

You don't need to release anything. ARC will take care of it when deallocating your view controller.

viewDidDisappear : only notifies the view controller that its view was removed from a view hierarchy. This is an optional method that your view can utilize to execute custom code when the view does indeed disappear. All views will be released automatically by ARC.

When you segue (presenting/pushing to a new scene), the previous view controller's views are generally not released. Only when a view controller is dismissed/popped (or you call an unwind segue) would it generally get deallocated. If you're seeing memory consumption continue to grow, make sure you are presenting/pushing to go forward, but dismiss/pop/unwind to return back to a previously presented view controller.

(A very long time ago, in low memory situations iOS would unload/release views that were not current visible, but Apple deprecated that in iOS 6.0 because it just didn't save much memory and caused too many problems for developers.)

Bottom line, because you're using ARC, you don't need this viewDidDisappear method at all. When the view is deallocated, that eliminates any strong references it maintains on its subviews, resulting in them being deallocated automatically, too (assuming you didn't create other strong references elsewhere, which you shouldn't be doing, anyway). Likewise, when the view controller is deallocated, any strong references it has are also resolved, resulting in those properties being released, too.


As an aside, a view controller maintains strong reference to the top level view , but it doesn't need to maintain strong references to that view's subviews. When addSubview is called, the top level view maintains its own strong references to its subviews. Thus the view controller owns the view, but the view owns its subviews.

This code sample suggest a bit of a logical inconsistency, where your IBOutlet is weak (as it should), but your label (and presumably the map ) are strong . This isn't going to cause a problem, but suggests a logical inconsistency in the object ownership diagram.

I might suggest making the playerLevel property (and map , presumably) weak references (just like the IBOutlet ). And, if instantiating these programmatically, you'd do something like:

@property (weak, nonatomic) UILabel *playerLevel;

- (void)viewDidLoad {
    [super viewDidLoad];

    UILabel *playerLevel = ...
    [self.view addSubview:playerLevel];
    self.playerLevel = playerLevel;
}

So, we create a local UILabel variable, configure it, add it to the subview, and then set the weak property to reference that label. The use of that local variable is important when dealing with weak properties, so it doesn't get released before you have a chance to call addSubview .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM