1. 程式人生 > >iOS Auto property synthesis will not synthesize property 'XXX'

iOS Auto property synthesis will not synthesize property 'XXX'

Auto property synthesis will not synthesize property 'XXX';
it will be implemented by its superclass, use @dynamic to acknowledge intention

父類中已經有一個這樣的屬性,而你又在子類中進行了宣告,編譯器就會給出警告

通過宣告屬性,我們可以很簡單的為一個成員變數定義其是否是隻讀的還是讀寫的,是否是原子操作的等等特性,也就是說如果說封裝是為成員變數套了一層殼的話,那麼 @property關鍵字做的事情就是預定義這層殼是個什麼樣子的殼,然後通過@sythesize

關鍵字生成真正的殼並把這個殼套在實際的成員變數上(如果沒有定義這個成員變數該關鍵字也可以自動生成對應的成員變數)。當然這層殼包括了自動生成的 get set 方法。
在最開始的時候,我們在程式碼中寫了@property對應的就要寫一個@sythesize在蘋果使用了 LLVM 作為編譯器以後,如果我們沒有寫 @sythesize,編譯器就會為我們自動的生成一個 @sythesize property = _property。這個特性叫做Auto property synthesize

當我們想要覆蓋父類的屬性並且做出修改的時候,Auto property synthesize

就不知道自己該幹啥了,那編譯器也不會生成@sythesize property = _property但是已經@property了,此時如果仍舊使用父類的殼,在有些情況下會產生執行時crash,比如:一個屬性在父類中是readonly特性,但是在子類中聲明瞭readwrite特性,因為父類中是readonly不會生成set方法,但是在子類中如果呼叫set方法,就會crash

附上crash原因:

Terminating app due to uncaught exception 'NSInvalidArgumentException', 
reason: '-[Class setXXX:]: unrecognized selector sent to instance

所以遇到這種情況,我們解決方法就是,在子類.m中顯式的宣告一個 @synthesize XXX = _XXX 即可,如:

#import "LPMySelfShopListModel.h"

@implementation LPMySelfShopListModel
@synthesize ctitle = _ctitle;//適用於所有特性的資料型別
/*  或者 **/
//@dynamic ctitle;//對改變讀寫特性的屬性,不適用
@end