31

我被objective-c属性困住了。我需要的是为变量分配一个只写属性,与只读相反,即变量可以有setMethod,但不应该有getMethod。我不知道该怎么做。感谢您提供一些代码片段的答案。

4

3 回答 3

53

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

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

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


这种方法的主要优点是您实际上拥有一个真实的属性TM而不是由实例变量和设置器伪造的代理项,这意味着:

  • 在 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

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

于 2013-09-05T13:26:08.773 回答
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

如果您尝试读取虚假属性,编译器会警告您。

于 2010-11-24T11:30:01.550 回答
5

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

于 2010-11-24T11:27:57.730 回答