在ObjectiveC中,是否有必要为readonly属性声明强vs复制?

时间:2015-06-19 13:14:00

标签: objective-c

在Objective-C中,将NSString / NSArray / NSDictionary声明为副本是常见的,是否有必要为readonly属性执行此操作,或者没有区别?如果NSString是只读的,它永远不会被设置,所以声明它强或复制会产生相同的效果吗?

  

//在这里使用强而非复制,因为它会起作用   永远不会被复制?

     

@property(nonatomic,readonly)NSString * string;

3 个答案:

答案 0 :(得分:5)

如果它确实是只读的,那么您不需要指定它。如果您要私下将其重新声明为readwrite,那么您确实要指定它。对于readonly属性,它不起作用,因为不会创建任何setter。

答案 1 :(得分:0)

你是对的,但还有一些事情需要考虑。这很好,因为你的属性是不可变对象。然而,并非总是如此。

我经常遇到的第一个例子是你的实现中有实际可变对象的时候。就像在实现中声明NSArray的属性一样,实际上可以是NSMutableArray。它的强引用属性getter将返回指向NSMutableArray的指针。并且,在某些时候,当你从对象请求NSArray时,你会遇到这种情况,并且需要花费一些时间而不是 - 繁荣! - 你的NSArray有多少不同的元素?我勒个去?在这种情况下,最好在getter中复制使用NSMutableArray的内部实现。

另一个例子是一些模型对象

@interface Person : NSObject <NSCopying>
@property NSString *name;
@property NSDate   *birthdate;
@end

你还有一些其他的属性接口

@property (strong, readonly) Person *person;

是的,您不会将不同的对象分配给此属性。但是,您可以修改其字段,因此它将代表一些完全不同的Person。如果您不想要这样的行为 - 请将其设为copy财产。或者使用访问方法将其设为私有以获取其字段

- (id) getHiddenPersonPropertyValueForKey:(NSString *)personPropertyKey;

或任何其他方式

答案 2 :(得分:0)

如果property表示真正不可变的值(NSArrayNSIndexSet等),那么只需readonly即可,因为它将按原样返回为不可变。

但是如果您的私人ivar是可变的(NSMutableArray ivar vs property&#39; s NSArray类型),您应该返回一份副本以防止未来内部更改泄漏到呼叫者&#39;国家。

@interface MyObject : NSObject {
    NSMutableArray *_array;
}

@property(nonatomic, readonly) NSArray *array;
// -or-
- (NSArray *)array;

@end

@implementation

@dynamic array; // only if @property was declared in interface

- (NSArray *)array
{
    return [_array copy];
}

@end

然后,来电者可以安全地保存物业的价值,并且即使不自行制作明确的副本,也希望更改:

self.array = [myObject array]; // e.g. 1 element
[myObject addElementToArray:@(42)];
NSLog(@"%@", self.array); // still 1 element