我曾经这样做,直到我发现我的一个保留的属性的保留计数在dealloc函数之前为零。 (这种情况是正常还是异常?)
注意:这是一个RC条件,而不是ARC。
例如,我在下面有4个保留属性,它们是否总是以dealloc函数释放?
如果没有,我怎么知道什么时候发布,什么时候不发布?手动判断retainCount?
@property (nonatomic, retain) NSString *fileName;
@property (nonatomic, retain) UIImage *fullSizeImage;
@property (nonatomic, retain) UIImage *thumbnailImage;
@property (nonatomic, retain) UIImageView *checkedImageView;
- (void)dealloc {
[checkedImageView release];
checkedImageView = nil;
[fileName release];
fileName = nil;
[fullSizeImage release];
fullSizeImage = nil;
[thumbnailImage release];
thumbnailImage = nil;
[super dealloc];
}
答案 0 :(得分:3)
好吧,如果问题是“总是?”,那么Wain几乎是正确的......
简短的答案是肯定的......
因为一般情况下,当有人设置属性时,这意味着他将使用它作为属性,即他使用其setter方法初始化它。
但是(长答案):不,不要总是:
如果您在代码中的某个位置初始化与该属性关联的私有var而没有它的setter方法,该怎么办?请记住,属性不是var,而只是从Xcode获取方法以获取和设置与之关联的var的有用方法。
换句话说,当你写.h:
@property (nonatomic, retain) NSString *fileName;
和.m:
@synthesize fileName;
您正在声明一个名为fileName的var,并要求xcode为您创建2个(不可见)方法:
一个setter,用于在fileName中设置一个新的保留值:
-(void)setFileName:(NSString *)newString{
if (fileName == newString) {
return;
}
NSString *oldString = fileName;
fileName = [newString retain];
[oldString release];
}
和一个getter,用于获取fileName的值:
-(NSString)fileName{
return fileName
}
所以,当你在代码的某个地方使用时:
self.fileName = @"ciao";
你正在使用属性setter方法,就像你直接调用它一样(你可以这样做,隐形方法setFileName:真的存在):
[self setFileName:@"ciao"];
这样做,正如你在setter方法中看到的那样,从现在开始就保留了fileName,所以你应该在dealloc中释放它。
但是,回答你的问题:
如果您使用点规则在var中设置一个新字符串,那么一切都很好, 但是你可能决定以某种标准的方式设置它,可能只是为了错误:
fileName = @"ciao";
// code
fileName = @"Hallo";
// code
fileName = @"Bye";
这种方式你没有使用属性setter方法,但你直接使用var,所以不保留fileName,如果你试图释放它,那么你可能会崩溃...
PS: 手动判断retainCount?
不,永远不要那样做
答案 1 :(得分:2)
是的,它们应始终在dealloc
中发布。如果你得到dealloc并且某些内容已经发布但未设置为nil
那么你在应用程序的其他地方的内存管理方面做错了。
技术上在dealloc
中你不需要在发布后设置为nil
,但在发布后设置为nil通常是个好主意。
答案 2 :(得分:2)
您的dealloc
不必要地为每个属性调用getter,然后立即释放它。只需指定nil
即可发布属性:
- (void)dealloc {
self.checkedImageView = nil;
self.fileName = nil;
self.fullSizeImage = nil;
self.thumbnailImage = nil;
[super dealloc];
}
虽然如果你遵循让clang自动生成你的支持实例变量的当前趋势,那么这更好,因为它不会导致KVO副作用:
- (void)dealloc {
[_checkedImageView release];
[_fileName release];
[_fullSizeImage release];
[_thumbnailImage release];
[super dealloc];
}
答案 3 :(得分:0)
是的,它们通常都应该被释放。如果你的保留计数为零,那通常意味着你在内存管理代码中的某个地方犯了一个错误。
你问:如果没有,我怎么知道什么时候发布,什么时候不发布?手动判断retainCount?
可能,但您也可以使用静态分析让Xcode帮助您。转到Product -> Analyze
。它经常会帮助您找到错误的版本等。
答案 4 :(得分:0)
何时发布?很明显,如果你的对象持有对另一个对象的引用,并且你的对象消失了,那么它应该停止对另一个对象的引用。你为什么要查看保留计数?保留计数是关于持有相同对象的其他人,但它们不属于您的业务。他们应该知道他们在做什么。所以你释放对象。你做你的工作;其他人都必须做他们的。正如其他人所说,最简单的方法就是分配
self.someproperty = nil;
如果你的对象是唯一一个持有引用的对象,那么另一个对象就会消失。如果其他人有参考,它就不会消失。正如每个人都期望的那样。 "发布"方法应该是唯一一个关心对象的保留计数的人。