Ios 保留的属性应始终在dealloc函数中释放,对吗?

Ios 保留的属性应始终在dealloc函数中释放,对吗?,ios,Ios,我以前经常这样做,直到我发现在dealloc函数之前,我的一个保留属性的保留计数为零。(这种情况是正常还是异常?) 注:这是RC条件,不是ARC 例如,我在下面得到了4个保留属性,它们是否应该总是在dealloc函数中释放 如果没有,我怎么知道什么时候发布,什么时候不发布?手动判断重新计数 @property (nonatomic, retain) NSString *fileName; @property (nonatomic, retain) UIImage *fullSizeImage;

我以前经常这样做,直到我发现在dealloc函数之前,我的一个保留属性的保留计数为零。(这种情况是正常还是异常?)

注:这是RC条件,不是ARC

例如,我在下面得到了4个保留属性,它们是否应该总是在dealloc函数中释放

如果没有,我怎么知道什么时候发布,什么时候不发布?手动判断重新计数

@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];
}

是的,它们应该总是在
dealoc
中发布。如果您进入dealloc,并且某些内容已发布,但未设置为
nil
,则说明您在应用程序的其他位置的内存管理有问题


从技术上讲,在
dealoc
中,您不需要在发布后设置为
nil
,但在发布后设置为nil通常是个好主意。

是的,它们通常都应该被发布。如果retain计数为零,通常意味着您在内存管理代码中的某个地方犯了错误

你问:如果不是,我怎么知道什么时候发布,什么时候不发布?手动判断重新计数

@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];
}

可能,但是您也可以让Xcode帮助您,使用静态分析。转到
产品->分析
。它通常会帮助您找到错误的发布,等等。

您的
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];
}
好吧,如果问题是“总是?”,那么Wain几乎是对的

简短的回答是肯定的

因为一般来说,当某人设置一个属性时,这意味着他将把它作为一个属性来使用,也就是说,他使用它的setter方法来初始化它

但是(长回答):不,不总是:

如果在代码中的某个地方,在没有setter方法的情况下初始化与属性关联的私有var,会怎么样?请记住,属性不是var,而是从Xcode获取方法以获取和设置与其关联的var的有用方法

换句话说,当您在.h中写入时:

@property (nonatomic, retain) NSString *fileName;
以m为单位:

@synthesize fileName;
您正在声明一个名为fileName的var,并要求xcode为您创建2个(不可见)方法:

setter,用于在文件名中设置新的保留值:

-(void)setFileName:(NSString *)newString{
    if (fileName == newString) {
        return;
    }
    NSString *oldString = fileName;
    fileName = [newString retain];
    [oldString release];
}
-(NSString)fileName{
   return fileName
}
和一个getter,用于获取fileName的值:

-(void)setFileName:(NSString *)newString{
    if (fileName == newString) {
        return;
    }
    NSString *oldString = fileName;
    fileName = [newString retain];
    [oldString release];
}
-(NSString)fileName{
   return fileName
}
因此,当您在代码中的某个地方使用:

self.fileName = @"ciao";
您使用的是属性setter方法,就像您直接调用它一样(您可以这样做,不可见的方法setFileName:really exist):

这样做,正如您在setter方法中看到的,从现在起,fileName将被保留,因此您应该在dealloc中释放它

但是,要回答你的问题:

如果使用点规则在变量中设置新字符串,好的,一切正常, 但您可能会决定在某个地方以标准方式设置它,可能只是因为错误:

    fileName = @"ciao";
    // code
    fileName = @"Hallo";
    // code
    fileName = @"Bye";
这样,您就不用使用属性设置器方法,而是直接使用var,因此文件名不会被保留,如果您试图释放它,那么您可能会遇到崩溃

附言: 手动判断重新计数

@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];
}

不,永远不要这样做

什么时候释放?很明显,如果您的对象持有对另一个对象的引用,并且您的对象消失了,那么它应该停止持有对另一个对象的引用。你为什么还要看这个数字?“保留计数”是指其他人持有相同的对象,但他们与您无关。他们应该知道自己在做什么。所以你释放了这个物体。你做你的工作;其他人都要做自己的事。正如其他人所说,最简单的方法是分配

self.someproperty = nil;

如果您的对象是唯一一个持有引用的对象,那么另一个对象将消失。如果其他人持有推荐信,它不会消失。正如大家所期待的那样。“release”方法应该是唯一关心对象保留计数的方法

非常感谢,您的回答帮助我理解了
self.property1=XXX
property1=XXX