在 Objective-C 中只写属性

Posted

技术标签:

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

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

【问题讨论】:

只写属性有什么用?恕我直言,这只是浪费内存。 用途广泛;通常,当您希望某些内容是公开的只写和内部的类时,它是可读写的。 当外部类知道需要传入的变量但没有理由知道它当前设置为什么时。 【参考方案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 可以使用它吗?

以上是关于在 Objective-C 中只写属性的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Perl 中只写文件的某些行?

ios学习路线—Objective-C(属性修饰符)

什么作为属性属性在objective-c中完全做了什么?

比较 Objective-C 中的 2 个对象

Objective-c KVO:object vs changeDictionary

对象的扩展