在Objective-C中只写属性

时间:2010-11-24 11:23:12

标签: iphone objective-c iphone-sdk-3.0 properties accessor

我坚持使用objective-c属性。我需要的是为变量分配一个只写属性,与readonly完全相反,即变量可以有setMethod,但它不应该有getMethod。我不知道怎么做。一些代码片段的答案很受欢迎。

3 个答案:

答案 0 :(得分:49)

另一种有效方法是声明普通属性并使getter不可用

@interface MyClass
@property NSString * var;
- (NSString *)var UNAVAILABLE_ATTRIBUTE;
@end

如果有人试图访问getter,这将引发编译时错误。


这种方法的主要优点是你实际上有一个不动产 TM 而不是由实例变量和一个setter伪造的代理,这意味着:< / p>

  • 在Xcode中使用点符号时,您将获得自动完成功能
  • 所有运行时函数,例如class_getPropertyclass_copyPropertyList将按预期工作。

也就是说,无论如何都会合成getter实现,并且可以使用类似

的方式调用它
NSString * string = [myObj performSelector:@selector(var)];

或使用NSInvocation(如果是非id属性)

如果您是偏执狂并且确实想要阻止客户端调用getter,您可以通过提供自己的实现来显式抛出异常。

@implementation MyClass
- (int)var {
    [NSException raise:NSInternalInconsistencyException
                format:@"property is write-only"];
}
@end

无论如何,如果有人真的想要篡改你的实例变量,他们可以使用运行时来访问它,所以考虑到用例,最后的预防措施可能没用。您正在寻找编译时错误。

答案 1 :(得分:12)

您可以执行以下操作:

@interface MyClass {
@private
int _var;
}

- (void)setVar:(int)newVar;
@end

@implementation MyClass
- (void)setVar:(int)newVar {
_var = newVar;
}
@end

现在您可以像只写的属性一样访问变量var

@implementation SomeOtherClass
...
MyClass c = [[MyClass alloc] init];
c.var = 3;
...
@end

如果你试图读取假属性,编译器会警告你。

答案 2 :(得分:5)

这有什么理由需要成为财产吗?我只是将setter声明为方法并使用正常的[foo setVar:bar]语法。