使用ARC进行iOS内存管理

时间:2015-07-22 14:42:56

标签: ios xcode memory-management

让我们说我正在处理一个有大量视图的应用程序,当UIViewController转向另一个UIViewController时,我在理解内存管理方面遇到了一些问题。

我应该在viewDidDisappear中发布以下哪个对象:?

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

@property (strong,nonatomic) UILabel *playerLevel;

- (void)viewDidLoad
{
    [super viewDidLoad];

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

这是正确的方法吗?

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

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

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

4 个答案:

答案 0 :(得分:4)

你不需要做任何事情。 ARC 将为您实施dealloc方法,该方法将调用您保留属性的所有版本。

我真的建议你阅读apple的内存管理文档,这将有助于理解 ARC 的确在做什么,包括了解如何避免保留周期。

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

答案 1 :(得分:1)

您不需要发布任何内容。在取消分配视图控制器时,ARC将负责处理它。

答案 2 :(得分:1)

viewDidDisappear:仅通知视图控制器其视图已从视图层次结构中删除。这是一个可选方法,当视图确实消失时,您的视图可以利用该方法执行自定义代码。所有视图将由ARC自动发布。

答案 3 :(得分:0)

当您设置(显示/推送到新场景)时,先前视图控制器的视图通常发布。仅当视图控制器被解除/弹出(或者您调用解除segue)时,它才会被解除分配。如果您看到内存消耗继续增长,请确保您正在展示/推动前进,但请关闭/弹出/展开以返回到先前呈现的视图控制器。

(很久以前,在内存不足的情况下,iOS会卸载/发布当前不可见的视图,但Apple在iOS 6.0中不赞成使用它,因为它只是没有节省太多内存并且给开发人员带来了太多问题。 )

一句话,因为您使用的是ARC,所以根本不需要这种viewDidDisappear方法。当取消分配视图时,它会消除它在子视图上维护的任何强引用,从而导致它们自动被释放(假设您没有在其他地方创建其他强引用,无论如何您都不应该这样做)。同样,当取消分配视图控制器时,它的所有strong引用也会被解析,从而导致这些属性被释放。

另外,视图控制器维护strong对顶级view的引用,但不需要维护strong对该视图的子视图的引用。调用addSubview时,顶级视图会维护自己对其子视图的强引用。因此视图控制器拥有视图,但视图拥有其子视图。

此代码示例表明存在一些逻辑上的不一致,IBOutletweak(应该如此),但您的标签(可能是map)是{{1 }}。这不会导致问题,但建议对象所有权图中的逻辑不一致。

我可能会建议strong属性(和playerLevel,大概)map引用(就像weak一样)。并且,如果以编程方式实例化这些,您可以执行以下操作:

IBOutlet

因此,我们创建一个本地@property (weak, nonatomic) UILabel *playerLevel; - (void)viewDidLoad { [super viewDidLoad]; UILabel *playerLevel = ... [self.view addSubview:playerLevel]; self.playerLevel = playerLevel; } 变量,对其进行配置,将其添加到子视图,然后设置UILabel属性以引用该标签。在处理weak属性时,使用该局部变量很重要,因此在您有机会调用weak之前不会释放它。