Nelson 寫些 iOS 開發的東東

解決在 Xcode 5.1 底下複寫 property 所造成的 synthesis warning

| Comments

最近我將 Xcode 升級到最新的 5.1,然後原本都沒事的原始碼,卻遇到了 property synthesis 相關的 error,錯誤訊息大概長得像這樣:

Warning: Auto property synthesis will not synthesize property 'XXX' because it is 'readwrite' but it will be synthesized 'readonly' via another property

花了一些時間,終於找到問題所在。


我有個 super-class,它有公開一些 readonly property,它的 sub-class 因為某些原因需要把這個 property 改成 readwrite。這應該是個蠻常見的使用情境,範例大致上長得像這樣:

// Super-class, .h
@interface Car : NSObject
@property (nonatomic, copy, readonly) NSString *name; // 只公開 readonly property
@end

// Super-class, .m
@implementation Car()
@property (nonatomic, copy, readwrite) NSString *name; // 實作時改成 readwrite property
@end
// Sub-class, .h
@interface Tesla : Car
@end

// Sub-class .m
@interface Tesla()
@property (nonatomic, copy, readwrite) NSString *name; // sub-class 因為有特別需求,所以將公開的 readonly property 改成 readwrite
@end

就是這樣的程式碼,會讓 name property 出現 warning。原因是因為 compiler 讀取 sub-class 時,會發現 name 明明應該是個 readonly property(super-class 講的),但你卻要將它設為 readwrite property,所以 compiler 不知道該怎麼 auto synthesis。

但你知道 super-class 的實作,也會將這個 property 改成 readwrite,因此你在 sub-class 的實作裡這樣子寫是不會有問題的。可是 compiler 不知道啊,這要怎麼辦呢?

你要告訴 compiler,要它不用擔心。那要怎麼告訴 compiler 呢?你需要的是 @dynamic,它是一種給 compiler 的「承諾」,承諾它「雖然你現在不知道該怎麼辦,但是在 runtime 的時候你就會知道了」。所以只要把程式碼改成以下這樣就可以了:

// Sub-class .m
@implement Tesla
@dynamic name;
....
@end

以上,希望能幫到一些人 :-)

Comments

comments powered by Disqus