属性实现没有泄漏,只要您使用 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