【问题标题】:Write only property in Objective-C在 Objective-C 中只写属性
【发布时间】:2011-05-15 01:13:33
【问题描述】:

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

【问题讨论】:

  • 只写属性有什么用?恕我直言,这只是浪费内存。
  • 用途广泛;通常,当您希望某些内容是公开的只写和内部的类时,它是可读写的。
  • 当外部类知道需要传入的变量但没有理由知道它当前设置为什么时。

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


【解决方案1】:

是否有任何理由需要将其作为属性?我只是将 setter 声明为方法并使用普通的[foo setVar:bar] 语法。

【讨论】:

  • 是的,这行得通,但 xCode 似乎不会在您键入时自动完成 var。
  • @FredrikJohansson 你是对的。对于自动完成友好的解决方案,您可能需要查看我的解决方案。
【解决方案2】:

你可以这样做:

@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

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

【讨论】:

  • 需要在实现和接口中定义一个方法-(void)setVar:(int)newVar
  • @kubbing 从技术上讲,它是一个属性。 Obj-C 中的属性只是 getter 和 setter 这两种方法的花哨名称。您可以在不使用@property 的情况下声明getter,其行为将与@property 完全相同。这同样适用于二传手。您甚至可以使用点符号。
  • @Sulthan 这几乎是正确的,部分原因是运行时做出了这种区分。例如,像这样的 fake 属性在使用 class_copyPropertyList 时不会被列出。请参阅我的答案以了解不同的方法。
  • @Sulthan 同意。可能我的解决方案的最大优势是自动完成(而且它也更短;))。
  • 如果你在 Swift 中使用这个类,让它成为一个真实的属性会有所不同。如果它不是属性,则不能在 Swift 中使用点表示法。
【解决方案3】:

另一种有效的方法是声明普通属性并使 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

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

【讨论】:

  • LLVM 可以使用它吗?
猜你喜欢
  • 2011-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-14
  • 2012-12-25
  • 1970-01-01
  • 2011-06-10
相关资源
最近更新 更多