愚蠢的问题,但是为什么在声明财产时需要使用“保留”呢?分配某些内容时,它是否会被保留?

查看此示例,似乎在分配时会自动保留一个对象,那么这是什么意义呢?

#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都会在功能末尾释放对象,但是它不会被划分,因为我们仍然可以保留以前保持其生存。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top