2010-11-24 36 views
26

我被objective-c屬性卡住了。我需要的是爲變量指定一個只寫屬性,與readonly完全相反,即變量可以有setMethod,但它不應該有getMethod。我不知道該怎麼做。一些代碼片段的答案表示讚賞。在Objective-C中只寫屬性

+2

什麼是隻寫屬性的用法?恕我直言,這只是對內存的浪費。 – Eimantas 2010-11-24 11:25:08

+20

許多用途;通常當你想要某些東西是公開的只寫和內部到這個類時,它就是readwrite。 – bbum 2010-11-24 19:36:44

+0

當外部類知道需要傳入的變量但沒有理由知道當前設置的變量時。 – ArtOfWarfare 2013-10-20 19:28:39

回答

11

你可以這樣做:

@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 

如果你嘗試讀取假屬性編譯器會警告你。

5

這是否有任何理由需要屬性?我只是聲明setter作爲一種方法,並使用正常的[foo setVar:bar]語法。

+5

或者使用點語法...`foo.var = bar;`仍然可以工作。 – bbum 2010-11-24 19:37:27

44

另一種有效的方法是申報普通財產,使吸氣不可用

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

這將提高的情況下,有人試圖訪問的吸氣劑編譯時錯誤。


這種方法的主要優點是,你實際上有一個不動產TM,而不是由一個實例變量和一個setter僞造的替代品,這意味着:

  • 你在Xcode中使用點符號時會自動完成
  • 所有運行時功能,如class_getPropertyclass_copyPropertyList將按預期工作。

這就是說,吸氣實現反正合成,它可以使用類似

NSString * string = [myObj performSelector:@selector(var)]; 

或使用NSInvocation調用(在非id財產的情況下)

如果你是偏執和你真的想要阻止客戶端調用getter,你可以通過提供你自己的實現明確地拋出一個異常。

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

無論如何,如果有人想認真與你的實例變量篡改,他們可以使用運行時訪問它,所以給出的使用情況下,最後的預防措施很可能是無用的。編譯時錯誤是你真正想要的。