分配初始化属性两次导致ARC Objective C中的内存泄漏?

Bry*_*mas 4 memory-management objective-c automatic-ref-counting

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

self.myProperty = [[MyClass alloc] initWithBla:bla blur:blur];
self.myProperty = [[MyClass alloc] initWithBla:bla blur:blur];
Run Code Online (Sandbox Code Playgroud)

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

ric*_*ter 11

在属性实现中没有泄漏,只要您使用ARC,在您分配给属性的地方也没有泄漏.

呼叫:

self.myProperty = something
Run Code Online (Sandbox Code Playgroud)

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

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

以前由该物业持有的物品被释放,因此它不会泄漏.如果您使用ARC,编译器生成的代码也会以相同的方式工作.

你注意到泄漏的可能性是正确的,尽管不是(据我所知)你怀疑的地方.

self.myProperty = [[MyClass alloc] initWithBla:bla blur:blur];
Run Code Online (Sandbox Code Playgroud)

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

self.myProperty = [[[MyClass alloc] initWithBla:bla blur:blur] autorelease];
Run Code Online (Sandbox Code Playgroud)

但是,再次使用ARC,你就可以了.


要从注释中解决相关问题:这仍然没问题 - 但仅限于ARC - 如果您要分配给本地变量而不是self.myProperty.当你写:

id myLocalVar;
myLocalVar = [[MyClass alloc] initWithBla:bla blur:blur];
myLocalVar = [[MyClass alloc] initWithBla:bla blur:blur];
Run Code Online (Sandbox Code Playgroud)

编译器把它变成:

__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
Run Code Online (Sandbox Code Playgroud)