分配初始化属性两次是否会导致 ARC 目标 C 中的内存泄漏?



我有一段代码,它在功能上等价于:

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

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

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


从评论中解决相关问题:这仍然可以 - 但仅在 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

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

最新更新