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];
}
}