【问题标题】:does alloc init'ing a property twice result in a memory leak in ARC Objective C?两次分配初始化属性是否会导致 ARC Objective C 中的内存泄漏?
【发布时间】:2012-05-08 06:01:36
【问题描述】:

我有一段代码在功能上等同于:

self.myProperty = [[MyClass alloc] initWithBla:bla blur:blur];
self.myProperty = [[MyClass alloc] initWithBla:bla blur:blur];

我实际上并没有像上图所示连续两次这样做,但它实际上是正在发生的事情。我的问题是,这会导致 ARC Objective C 下的任何内存泄漏吗?在重新分配self.myProperty 以指向新分配的MyClass 实例之前,是否在第一次调用中为self.myProperty 分配的内存被回收?

【问题讨论】:

    标签: objective-c memory-management automatic-ref-counting


    【解决方案1】:

    属性实现没有泄漏,只要您使用 ARC,分配给属性的位置也没有泄漏。

    调用:

    self.myProperty = something
    

    调用类似这样的生成访问器(假设 _myProperty 是您的属性的支持 ivar):

    - (void)setMyProperty:(MyClass *)anInstance
    {
        if (_myProperty == anInstance)
            return;
        [_myProperty release];
        _myProperty = [anInstance retain];
    }
    

    该属性之前持有的对象被释放,所以它不会在这里泄漏。如果你使用 ARC,编译器生成的代码也是一样的。

    您指出泄漏的可能性是正确的,但不是(据我所知)您怀疑的地方。

    self.myProperty = [[MyClass alloc] initWithBla:bla blur:blur];
    

    这将创建一个保留计数为 +1 的新对象并将其分配给属性(然后再次保留它:+2)。因此,您在此处的代码仍然具有对该对象的所有权引用。当你重复那行时,你已经孤立了你仍然拥有的第一个引用——如果你使用的是 ARC,你很好:它确保对象被释放。如果没有,该孤立对象仍会保留:您确实有泄漏。适当的非 ARC 事情是:

    self.myProperty = [[[MyClass alloc] initWithBla:bla blur:blur] autorelease];
    

    但是,再一次,使用 ARC 就可以了。


    解决 cmets 的一个相关问题:如果您要分配给局部变量而不是 self.myProperty,这仍然可以 - 但仅在 ARC 下。当你写:

    id myLocalVar;
    myLocalVar = [[MyClass alloc] initWithBla:bla blur:blur];
    myLocalVar = [[MyClass alloc] initWithBla:bla blur:blur];
    

    编译器把它变成:

    __strong id myLocalVar; // variables are strong by default
    myLocalVar = [[MyClass alloc] initWithBla:bla blur:blur];
    [myLocalVar release]; // ARC inserts release before myLocalVar is reassigned to another object
    myLocalVar = [[MyClass alloc] initWithBla:bla blur:blur];
    // ... sometime later ...
    [myLocalVar release]; // ARC inserts another release when myLocalVar goes out of scope
    

    【讨论】:

    • @rickster 如果我们使用 ARC 并且对象是本地的并初始化两次怎么办?
    • 查看编辑后的答案。请注意,增加其保留计数的不是initing 对象(ARC 为其插入平衡releases),而是alloc
    【解决方案2】:

    没关系,这里没有内存泄漏。这就是 ARC 的全部意义所在。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-20
      • 1970-01-01
      • 2021-09-16
      • 2013-05-23
      • 1970-01-01
      • 1970-01-01
      • 2019-11-24
      • 2019-08-12
      相关资源
      最近更新 更多