以只读方式返回对象

时间:2011-12-07 12:13:26

标签: objective-c properties

如何从方法返回一个对象,因此对于调用者来说它是只读的? 请注意,这不是一个可以在声明getter声明时设置为只读的属性

@property(nonatomic,retain,readonly) NSDate* pub_date;

例如:

-(SomeClass*)getObject
{
  SomeClass* object = [[SomeClass alloc] init];
  //Don't allow writing to 'object'
  return object;
}

感谢。

2 个答案:

答案 0 :(得分:2)

简短回答:没有简单的方法可以做到这一点。

更长的答案:Apple的框架为其集合类定义了一种标准,其中不可变集合是基类,而可变集合是继承类。因此,例如,NSMutableArray继承自NSArray。您可以遵循该标准,并拥有将MyClass返回给客户端的方法,同时在其中使用MyMutableClass。从技术上讲,客户端仍然可以发送变异消息,当然,但恕我直言,这不是一个很大的风险(毕竟,客户端不知道您的实现细节)。

还有其他更复杂的选项 - 你可以使用指针调配,子类和覆盖所有变异方法,或者只是将可变类复制到一个不可变的对应物(这不复杂但可能会导致性能损失)。但为了获得最佳效果,您应该遵循Apple的例子。

答案 1 :(得分:1)

这取决于对象是什么。如果它有一个可变/不可变对(如NSString / NSMutableString),那么你的getter方法可以返回不可变版本。

否则,你无法控制其他对象的行为 - 一旦你返回了一个对象,就无法从最初提供它的对象中控制它。

如果您担心另一个对象可能会改变从getter返回的对象,从而修改原始对象中保存的属性,那么您应该返回该对象的副本。

示例:

对象A具有可变字符串属性,对象B请求此可变字符串,getter直接返回支持该属性的实例变量。

对象B然后更改字符串 - 对象A的属性也被修改,因为两个对象都有一个指向同一可变字符串的指针。

在这种情况下,您将返回对象的副本而不是对象本身。如果您的对象是自定义对象,则必须实现NSCopying协议才能允许此对象。

进一步说明 - 将属性声明为只读意味着不会生成任何setter访问器 - 即objectA.property = newValue;将导致编译器错误。