4

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

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

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

4

2 回答 2

11

属性实现中没有泄漏,只要您使用 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 你就好了。


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

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
于 2012-05-08T06:31:01.920 回答
2

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

于 2012-05-08T06:18:22.247 回答