【问题标题】:A question about setter in objective-c关于objective-c中setter的一个问题
【发布时间】:2009-07-16 15:13:43
【问题描述】:

这是一个来自 The Objective-C 2.0 Programming Language 的例子。 我只是想知道,在底部的设置器中,我可以使用value = [newValue retain] 而不是value = [newValue copy]

    @interface MyClass : NSObject

{

    NSString *value;

}

@property(copy, readwrite) NSString *value;

@end



// assume using garbage collection

@implementation MyClass

@dynamic value;



- (NSString *)value {

    return value;

}



- (void)setValue:(NSString *)newValue {

    if (newValue != value) {

       value = [newValue copy];

    }

}

@end

【问题讨论】:

    标签: objective-c memory copy setter retain


    【解决方案1】:

    最快最安全的做法是将@synthesize value 添加到您的实现顶部,编译器会自动生成这些方法。

    复制与保留的问题取决于您可能会传入一个 NSMutableString,这会改变它的值。如果您有一个“不可变”类型(字符串、集合、数组、字典)的设置器,则需要使用 copy 语义。起初这可能看起来违反直觉(如果它是不可变的,为什么还要制作副本?)但要意识到的是,您的类想要假设它是不可变的,而传入的可能实际上不是不可变的。

    NSMutable 类通过返回它们所代表的不可变版本来实现 copy 选择器。不可变类(NSString 等)通过 retain 调用实现 copy。也就是说,它们非常快。

    您的 setter 还需要释放 value,然后再为其分配新值。正确的代码是:

    -(void)setValue:(NSString*)newvalue
    {
        if (value != newvalue)
        {
            [value release];
            value = [newvalue copy];
        }
    }
    

    如果您可以完全控制所有可能调用 setValue: 的类,并且绝对确定不会传入 NSMutableString,则可以使用 retain,但最好使用 copy

    【讨论】:

    • 总是使用副本是个好主意吗?另外,我可以说 @property(retain, copy, readwrite) NSString *value ,效果会怎样?谢谢
    • 那不会编译。当您期望/希望该项目从您的班级的可见性中不可变时,使用副本是一个好主意。如果你有一个不代表值的东西的属性(例如 UI 出口属性),请使用 retain。
    【解决方案2】:

    这取决于。如果您使用[newValue retain],另一个对象可能会更改此NSString 指针的值。通常,您不喜欢这种行为。

    【讨论】:

      【解决方案3】:

      不,您的界面显示copy。如果有人传入 NSMutableString,这两种方法会得到非常不同的结果。

      【讨论】:

      • 通过 API,Church 表示您对 value 属性的声明。两者都应该是copyretain
      • 所以通过使用 copy 我可以跳过类型检查以避免运行时错误,是这样的想法吗?
      【解决方案4】:

      setter 方法:

        -(void)setValue:(NSString*)newvalue{
              if (_value != newvalue)
              {
                  [_value release];
                  _value = nil;
                  _value = [newvalue copy];
      
              }
         }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-28
        • 1970-01-01
        • 1970-01-01
        • 2021-01-26
        • 2011-11-11
        • 1970-01-01
        相关资源
        最近更新 更多