题
愚蠢的问题,但是为什么在声明财产时需要使用“保留”呢?分配某些内容时,它是否会被保留?
查看此示例,似乎在分配时会自动保留一个对象,那么这是什么意义呢?
#import "Fraction.h"
#import <stdio.h>
int main( int argc, const char *argv[] ) {
Fraction *frac1 = [[Fraction alloc] init];
Fraction *frac2 = [[Fraction alloc] init];
// print current counts
printf( "Fraction 1 retain count: %i\n", [frac1 retainCount] );
printf( "Fraction 2 retain count: %i\n", [frac2 retainCount] );
// increment them
[frac1 retain]; // 2
[frac1 retain]; // 3
[frac2 retain]; // 2
// print current counts
printf( "Fraction 1 retain count: %i\n", [frac1 retainCount] );
printf( "Fraction 2 retain count: %i\n", [frac2 retainCount] );
// decrement
[frac1 release]; // 2
[frac2 release]; // 1
// print current counts
printf( "Fraction 1 retain count: %i\n", [frac1 retainCount] );
printf( "Fraction 2 retain count: %i\n", [frac2 retainCount] );
// release them until they dealloc themselves
[frac1 release]; // 1
[frac1 release]; // 0
[frac2 release]; // 0
■输出
分数1保留计数:1
分数2保留计数:1
分数1保留计数:3
分数2保留计数:2
分数1保留计数:2
分数2保留计数:1
交易分数
交易分数
这真让我抓狂!
解决方案
属性的默认行为是分配的,而不是保留。这些不是相同的行为。如果您的属性是针对原始数据类型(例如INT)的,则分配是正确使用的。但是,如果您指定(保留),并且该属性指向对象指针,例如nsobject *对象,则指示指针分配了对象的内存地址,并且保留计数会增加一个。如果您的程序仅包含一个孤独的主函数,那么目的就很难看到。但是,假设您的班级有此方法:
-(void)setMyArrayWithString:(NSString *)s{
myArray = [NSArray arrayWithObject:s];
}
假设MyArray定义为NsArray *MyArray,并具有适当的@property(retain)语句。一切正常,直到方法返回。这是因为从nsarray返回的对象是自我发行的对象。如果我们不保留它,它将由NSAUTUREELEASEPOOL发布,我们将无法使用它(我们会得到讨厌的错误和违规访问障碍)。为了解决这个问题,我们可以做两件事之一:
-(void)setMyArrayWithString:(NSString *)s{
self.myArray = [NSArray arrayWithObject:s];
// OR
myArray = [[NSArray arrayWithObject:s] retain];
}
第一个解决方案使用self.myarray来利用@property定义。该代码分配然后保留对象,因此当功能返回时,我们不会丢失它。第二个解决方案设置了NSArray *MyArray指针,然后手动保留NSArray对象。无论哪种方式,NSAUTOREELEASEPOOL都会在功能末尾释放对象,但是它不会被划分,因为我们仍然可以保留以前保持其生存。
不隶属于 StackOverflow