緣由是遇到了下面這個問題
重寫了屬性的
getter
和setter
方法后,編譯器提示對應的實例變量不存在计贰。
看了若干資料钦睡,理清了來龍去脈。
歷史
在Xcode 4.4 之前躁倒,我們在 .h 中寫完@proprety foo;
之后荞怒,都會在 .m 中寫上 @synthesize foo = _foo;
來為屬性生成訪問方法。
然后在Xcode 4.4 之后秧秉,我們只要寫了 @proprety foo;
就可以自動生成屬性的訪問方法褐桌。
具體原因,我們從@proprety
說起象迎。
@proprety
我們知道荧嵌,寫下@proprety
后,編譯器實際上是做了兩件事砾淌,生成getter 和 setter啦撮,給類中添加名為屬性名前加下劃線的實例變量。這個過程叫做自動合成汪厨。
@synthesize
然后@synthesize foo = _foo
做了什么事情呢赃春?
foo
屬性幫助 _foo
實例變量 提供 訪問器方法。也可以理解為:指定 _foo
為foo
屬性對應的實例變量
如果 _foo 實例變量沒有被聲明劫乱,@synthesize
會為類添加名為 _foo 的實例變量织中。
那 @synthesize foo;
做了什么事锥涕?
生成一個和 foo
同名的實例變量
@synthesize
實際上就相當于完成自動合成的過程,并且可以讓程序員指定實例變量狭吼。
失效的自動合成
然而层坠,Xcode 4.4 后,編譯器進行的自動合成刁笙,是有可能會失效的破花。這種情況發(fā)生在當編譯器判斷程序要手動管理屬性的時候,具體不會自動合成的場景如下
- 同時重寫了get set
- 重寫只讀屬性的 get
- 使用了@dynamic
- @protocol 中定義的屬性
- category中定義的屬性
- 重載的屬性:當你在子類中重載父類的屬性采盒,你必須用
@synthesize
手動合成 ivar
在文章開頭遇到的問題旧乞,就是因為我們重寫了屬性全部訪問器方法后,讓編譯器使得自動合成失效磅氨,從而編譯器不會自動編寫訪問器方法和生成Ivar
,于是我們在使用名為 下劃線+屬性 的實例變量的時候嫡纠,就提示實例變量不存在烦租。
解決方法
文章開頭問題的解決方法:
使用 @synthesize foo = _foo
,合成 _foo
實例變量除盏,并指定 foo 屬性 為(四聲) 它提供 get set 方法叉橱。
補充 @synthesize 合成實例變量的規(guī)則
- 如果指定了實例變量名稱,就會生成一個指定了名稱的成員變量者蠕。
@s foo = wtf_foo;//生成wtf_foo
- 如果這個實例變量存在窃祝,就不生成了。
@interface MyCls () {
NSString _foo;
}
@end
@implementation MyCls
@synthesize foo = _foo;
@end
- 如果沒有指定實例變量名稱踱侣,那就會自動生成一個和屬性同名的實例變量粪小。
@s foo; //就是生成 foo
補充 @dynamic
@dynamic 的意思就是跟系統(tǒng)說,不要創(chuàng)建 property 對應的成員變量(就是一般的 _someProperty)抡句,也不要自動生成 get/set 方法探膊,同時不要報錯,到在運行時我自己會來添加 get/set 方法待榔。(轉(zhuǎn)自【孫總的segmentfault】)