我想将自定义对象分配给实例变量。
这是代码:
- MyController.h / .m
#import "CustomData.h"
@interface MyViewController : NSViewController
@property (retain) CustomData* theData;
- (void)aRandomMethod;
@end
@implementation MyViewController
@synthetize theData;
- (void)aRandomMethod {
NSData* rawData = [someOtherObject someOtherMethod];
// option 1
self.theData = [[CustomData alloc] initWithData:rawData];
// option 2
CustomData* _theData = [[Custom alloc] initWithData:rawData];
// option 3
self.theData = [[[CustomData alloc] initWithData:rawData] autorelease];
// option 4
theData = [[CustomData alloc] initWithData:rawData];
// ... later code calls some methods on theData or _theData, not useful here.
}
@end
在Xcode中运行Analyze功能时,它告诉我,对于选项1和2,有一个“泄漏的对象未被引用...”,但对于3和4则没有。似乎我需要{{1使用setter时的自定义对象。我知道在返回方法中我们拥有的对象时需要使用autorelease
。
你能为每个选项解释为什么它是错的还是对的?感谢。
答案 0 :(得分:5)
选项1是错误的,因为你alloc
是该方法中的对象,因此该方法现在拥有该对象,因此需要release
它。当您将其分配给某个媒体资源时,retain
会将其release
分配给alloc
。当它完成时,它就会release
。
出于同样的原因,选项2是错误的。你取出它的属性部分,但因为你用autorelease
创建了对象,你负责用该方法调用release
。
选项3是正确的,因为在将它提供给属性之前你已release
,因此该方法不再拥有它。请注意,如果您在此处使用了retain
,那么它会中断,因为它会在release
财产获得{{1}}之前{{1}}。
选项4可能是正确的;我假设它正在将它分配给ivar。如果您稍后在dealloc方法中手动释放ivar,那么这是正确的。通过房产通常会更好。否则,您将面临分配其他值并忘记{{1}}现有值的风险。
答案 1 :(得分:1)
选项1和2最值得注意的是存在一个alloc,因此需要相应的版本。
选项1本质上是“隐藏的”,因为编译器会自动为您生成setter和getter。您没有看到的是,当使用点表示法时,您将通过setter,它隐含地包含一个保留调用。因此,您将分配对象AND retain,使其保留计数为2.
因此,为了确保将来能够正确发布,您必须将其指定为添加到自动释放池中,以便系统稍后进行清理。这将使保留计数为1,然后在您的dealloc方法中,您可以安全地释放该属性。