关于objective-c中setter的问题

时间:2023-02-04 22:24:00

This is an example from The Objective-C 2.0 Programming Language. I was just wondering, in the setter at the bottom, can I use value = [newValue retain] instead of value = [newValue copy] ?

这是Objective-C 2.0编程语言中的一个例子。我在想,在底部的setter中,我可以使用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

4 个解决方案

#1


7  

The quickest and safest thing to do would be to add @synthesize value to the top of your implementation, and the compiler will automatically generate these methods.

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

The issue of copy vs. retain hinges on the fact that you may be passed in a NSMutableString, which would change its value. If you have a setter for an 'immutable' type (string, set, array, dictionary), you need to use copy semantics. At first this may seem counterintuitive (why make a copy if it's immutable?) but the thing to realize is that your class wants to assume it is immutable, and what's passed in may not actually be immutable.

复制与保留的问题取决于您可能被传递到一个NSMutableString中,这会改变它的值。如果您有一个“不可变”类型的setter (string, set, array, dictionary),您需要使用复制语义。乍一看,这似乎有悖常理(如果它是不可变的,为什么要复制它?)但需要注意的是,您的类希望假设它是不可变的,而传入的内容实际上可能不是不可变的。

NSMutable classes implement the copy selector by returning an immutable version of what they represent. The immutable classes (NSString, etc) implement copy with a retain call. That is to say, they are very fast.

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

Your setter also needs to release value before assigning it a new value. The proper code is:

setter还需要在分配新值之前释放值。适当的代码是:

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

If you have complete control over all the classes that may call setValue: and are absolutely sure you won't be passing in NSMutableString, you can use retain, but it's best practices to use copy.

如果您完全控制了所有可能调用setValue的类:并且绝对确信不会传入NSMutableString,您可以使用retain,但是使用copy是最佳实践。

#2


0  

It depends. If you use [newValue retain], another object may change the value of this NSString pointer. Normally, you do not like to have this behaviour.

视情况而定。如果您使用[newValue retain],另一个对象可能会更改这个NSString指针的值。通常,你不喜欢有这种行为。

#3


0  

No, your interface says copy. If somebody passes in an NSMutableString, you will get very different results from the two methods.

不,你的接口说的是拷贝。如果有人传入一个NSMutableString,您将从这两个方法中得到非常不同的结果。

#4


0  

setter method:

setter方法:

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

        }
   }

#1


7  

The quickest and safest thing to do would be to add @synthesize value to the top of your implementation, and the compiler will automatically generate these methods.

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

The issue of copy vs. retain hinges on the fact that you may be passed in a NSMutableString, which would change its value. If you have a setter for an 'immutable' type (string, set, array, dictionary), you need to use copy semantics. At first this may seem counterintuitive (why make a copy if it's immutable?) but the thing to realize is that your class wants to assume it is immutable, and what's passed in may not actually be immutable.

复制与保留的问题取决于您可能被传递到一个NSMutableString中,这会改变它的值。如果您有一个“不可变”类型的setter (string, set, array, dictionary),您需要使用复制语义。乍一看,这似乎有悖常理(如果它是不可变的,为什么要复制它?)但需要注意的是,您的类希望假设它是不可变的,而传入的内容实际上可能不是不可变的。

NSMutable classes implement the copy selector by returning an immutable version of what they represent. The immutable classes (NSString, etc) implement copy with a retain call. That is to say, they are very fast.

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

Your setter also needs to release value before assigning it a new value. The proper code is:

setter还需要在分配新值之前释放值。适当的代码是:

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

If you have complete control over all the classes that may call setValue: and are absolutely sure you won't be passing in NSMutableString, you can use retain, but it's best practices to use copy.

如果您完全控制了所有可能调用setValue的类:并且绝对确信不会传入NSMutableString,您可以使用retain,但是使用copy是最佳实践。

#2


0  

It depends. If you use [newValue retain], another object may change the value of this NSString pointer. Normally, you do not like to have this behaviour.

视情况而定。如果您使用[newValue retain],另一个对象可能会更改这个NSString指针的值。通常,你不喜欢有这种行为。

#3


0  

No, your interface says copy. If somebody passes in an NSMutableString, you will get very different results from the two methods.

不,你的接口说的是拷贝。如果有人传入一个NSMutableString,您将从这两个方法中得到非常不同的结果。

#4


0  

setter method:

setter方法:

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

        }
   }