2015-09-28 65 views
4

所以我有一個協議,這需要一個屬性聲明:爲什麼我必須聲明由協議在標題中指定的屬性,而不是類擴展(實現)

@protocol MyProtocol <NSObject> 
@property MyView *myView; 
@end 

和實現文件(類擴展)的內部

@interface MyViewController : NSViewController <MyProtocol> 
@end 

但是,如果我申報財產(協議規定):對象誰符合它

@interface MyViewController() 
@property MyView *myView; 
@end 

我得到這個錯誤:

Illegal redeclaration of property in class extension 'MyViewController' (attribute must be 'readwrite', while its primary must be 'readonly')

似乎有是解決這個問題的兩個主要SO線程:
attribute must be readwrite while its primary must be read only

Can't declare another window

第一個答案沒有解釋任何東西

第二個答案說,你可以通過聲明屬性中的屬性來避免這個錯誤e頭;唉

@interface MyViewController : NSViewController <MyProtocol> 
@property MyView *myView; 
@end 

實施

@interface MyViewController() 
@end 

這建立沒有任何錯誤。

我也知道當你在一個協議中聲明一個@property時,它不會自動合成。

所以如果我想保留@property聲明在執行中,我將不得不@synthesize它。這也適用。


所以我的問題是,爲什麼不宣告頭VS實現文件此事的內部@property如果@property在協議內最初宣佈?

沒有協議,我認爲唯一的區別是使@property公共或私人。但很明顯,如果您在頭文件中聲明@property vs實施文件

+1

由於您公開聲明您的類符合協議(在.h文件中),您還必須公開聲明您擁有該屬性。如果您只希望該屬性是私有的,請遵守類擴展中的協議而不是公共接口。 – rmaddy

+0

我仍然得到這個錯誤:\我也不認爲我可以那樣做,因爲我的其他對象需要知道'MyViewController'符合'MyProtocol'--並且它看起來像沒有人知道它會如果我符合類擴展 –

+0

好的,那麼如果你需要公開聲明協議,那你爲什麼不公開聲明這個協議呢? – rmaddy

回答

4

不會發生其他事情發生/不會發生不要在類中的任何位置聲明屬性。它已經在協議中聲明。

請勿將@property MyView *myView;放入MyViewController.m或MyViewController.h文件中。

要解決關於「汽車財產合成」的警告,你只需添加:

@synthesize myView = _myView; 

MyViewController執行,或根據需要增加明確的getter和setter方法。

+0

因此,我假設通過在實現中聲明屬性爲'readwrite'並且在實現中聲明'readonly',編譯器只是假設由於某種原因自動綜合屬性? –

+1

在Xcode 7下,您不能在類擴展中聲明該屬性爲只讀(或讀寫)。 – rmaddy

+0

真棒,足夠說,再次感謝您的時間:) –

相關問題