保留iOS setter方法中的发布常用做法

时间:2012-09-28 14:19:00

标签: objective-c ios memory-management

IOS设置者的常见做法如下:

- (void)setMyString:(NSString *)newString {
    if ( newString != myString ) {
        [myString release];
        myString = [newString retain];
    }
}

相反,这不是好习惯

- (void)setMyString:(NSString *)newString {
    if ( myString != nil ) [myString release];
        myString = [newString retain];
    }
}

在第一种情况下检查平等的原因是什么?在秒的情况下有什么问题?

3 个答案:

答案 0 :(得分:2)

如果您设置类似此[object setMyString:[object myString]];的内容而不检查相等性 - 它将会崩溃!因为它会在你发送之前发布消息保留。 (如果只有对象拥有字符串)。同样在第一个例子中,我们检查相等性以避免额外的操作。

答案 1 :(得分:0)

您可以通过内存管理https://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/来实现此目的。

答案 2 :(得分:0)

我知道这有点多余,但是......

如果新旧对象相同,那么您将release发送到旧对象并取消分配,指向新对象的指针将变为悬空指针,因为它指向的对象将不再存在(因为它指向与旧对象指针相同的对象)。防爆。如果myStringnewString指向保留计数为1的同一实例,则减去1,它将等于零。现在添加一个为时已晚,因为它会被解除分配。但是,撤消对retainrelease的调用,应该没问题。如果保留计数为1并且您添加一个,它现在是两个,您可以安全地发送版本。一般来说,在你否定一个对象之前我会说,首先断言新对象的所有权。

此外,第一种类型的setter将用于retain / strong样式设置器。如果是assign,则不需要保留/释放,因为不应声明所有权。 NSStrings通常有一个copy样式的setter,它复制参数并使用它,这将创建一个副本而不是保留。我通常会将copy用于任何具有可变子类的内容,因为您不希望有人传入NSMutableString并将其改为背后。 This page进入访问器,你会发现它们在释放旧值之前会保留新值,并解释原因。