我想给一个实例变量分配一个自定义对象。
代码如下:
#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中的分析功能时,它告诉我有一个“泄漏的对象,以后没有引用...”用于选项1和2,而不是用于3和4。在使用autorelease
方法时,我似乎需要设置自定义对象。我知道在返回我们在方法中拥有的对象时需要使用autorelease
。
你能解释一下为什么每个选项都是错的还是对的吗?谢谢。
发布于 2013-04-16 22:17:36
选项1是错误的,因为你在该方法中alloc
对象,所以该方法现在拥有该对象,因此需要对它进行release
。当你将它赋给一个属性时,该retain
会检查它,并期望在使用完它时对它进行release
。
出于同样的原因,选项2是错误的。您去掉了它的属性部分,但是因为您是用alloc
创建的对象,所以您要负责在该方法中调用release
。
选项3是正确的,因为在将它提供给属性之前,您已经autorelease
d了它,所以该方法不再拥有它。请注意,如果您在这里使用release
,它将中断,因为它会在属性有机会对其执行release
之前对其执行retain
操作。
选项4可能是正确的;我假设它将其分配给一个ivar。只有当您稍后在dealloc方法中手动释放ivar时,它才是正确的。不过,一般情况下更好的做法是遍历属性。否则,您将冒着分配另一个值并忘记release
现有值的风险。
发布于 2013-04-16 22:21:52
对于选项1和选项2,需要注意的最重要的事情是存在分配,因此需要相应的版本。
选项1本质上是“隐藏的”,因为编译器会自动为您生成setter和getter。您没有看到的是,在使用点表示法时,您正在经历setter,它隐式地包含了一个保留调用。因此,您正在分配对象并保留,使其保留计数为2。
因此,为了确保将来能够正确释放它,您必须将其指定为添加到自动释放池中,以便系统稍后清理。这将使保留计数为1,然后在dealloc方法中,您可以安全地释放该属性。
https://stackoverflow.com/questions/16047968
复制