我遇到了一些关于Objective-C属性的问题。我需要为一个变量分配一个只写属性,与readonly完全相反,也就是说,该变量可以有setMethod
,但不应该有getMethod
。我不知道如何实现它。带有一些代码片段的答案会更好。
我遇到了一些关于Objective-C属性的问题。我需要为一个变量分配一个只写属性,与readonly完全相反,也就是说,该变量可以有setMethod
,但不应该有getMethod
。我不知道如何实现它。带有一些代码片段的答案会更好。
另一种有效的方法是声明普通属性并使getter不可用
@interface MyClass
@property NSString * var;
- (NSString *)var UNAVAILABLE_ATTRIBUTE;
@end
如果有人尝试访问这个getter,它会在编译时引发错误。
这种方法的主要优点是你实际上拥有一个真正的属性TM,而不是由实例变量和setter伪造的代理,那意味着:
class_getProperty
和class_copyPropertyList
)都将按预期工作。话虽如此,getter实现仍然是由程序自动生成的,并且可以通过类似以下方式调用:
NSString * string = [myObj performSelector:@selector(var)];
或者使用NSInvocation
(对于非id
属性)。
如果您十分担心并且确实想要防止客户端调用getter方法,您可以提供自己的实现来显式抛出异常。
@implementation MyClass
- (int)var {
[NSException raise:NSInternalInconsistencyException
format:@"property is write-only"];
}
@end
无论如何,如果有人真的想篡改您的实例变量,他们可以使用运行时来访问它,因此,最后一道防线在使用情况下可能是无用的。编译时错误是您真正寻找的。
你可以这样做:
@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
。 - JeremyP@property
,行为与使用 @property
完全相同。setter 也是如此。你甚至可以使用点符号表示法。 - Sulthanclass_copyPropertyList
列出时不会被列出。请参见我的答案以了解不同的方法。 - Gabriele Petronella这需要声明为属性吗?我只会将setter声明为方法,并使用正常的[foo setVar:bar]
语法。