久了不回顧基礎知識,猛然間看到,有時候還真想不起來有的知識,比如宣告@property和合成@synthesize的屬性與普通的屬性有什麼本質區別,self.a和_a訪問的區別,所以有必要回顧一下。
我們先來說說@property和@synthesize
@property宣告成員變數,會自動幫我們生成該成員變數的getter/setter方法的宣告;
@synthesize的作用是自動生成成員變數的getter/setter方法的定義;
所有被宣告為屬性的成員,在ios5 之前需要使用編譯器指令@synthesize 來告訴編譯器幫助生成屬性的getter,setter方法。之後這個指令可以不用人為指定了,預設情況下編譯器會幫我們生成。
這裡先淺顯的說明@property和synthesize的作用,其他的知識自己google,今天主要回顧self.a和_a的區別。
首先使用self.a會呼叫getter/setter方法,而_a並不會呼叫getter/setter方法,它是直接訪問例項變數並賦值。
下面我們通過@property的copy屬性舉例說明:
#import @inte***ce person : nsobject
@property (nonatomic, copy) nsstring *name;
@property (nonatomic, copy) nsstring ****;
- (void)changenamevalue:(nsstring *)newname andchange***value:(nsstring *)***value;
@end
上面是乙個person類,裡面有兩個成員變數name和***,宣告了乙個例項方法changenamevalue:andchange***value:,下面例項方法的實現:
#import "person.h"
@implementation person
- (void)changenamevalue:(nsstring *)newname andchange***value:(nsstring *)***value
@end
然後在viewdidload方法中呼叫:
- (void)viewdidload
執行後得到的結果:
執行結果
我們可以看到,newname和new***改變了,name的值仍然沒有變是tongry,而***的值確是改變了,末尾增加了「andwoman」.
實際上我們期待的是對類屬性的賦值是深拷貝賦值(我們宣告了@property的copy屬性),但是實際得到的結果是name進行了深拷貝,而***仍然是淺拷貝。究其原因,就是因為name是self訪問,***是_訪問。在呼叫self的時候,如果是賦值,那麼編譯器會自動根據strong/copy生成對應的setter方法,其實現類似於:
//宣告為copy屬性時
- (void)setname:(nsstring *)name
}//當宣告為retain屬性時(mrc下)
- (void)setname:(nsstring *)name
}
在上面的例子中,使用self.name賦值後,name已經和newname沒有指向同一塊記憶體,所以name沒有隨著newname值的改變而改變。_***賦值是直接指向了new***所指向的記憶體塊,也沒有做retain操作,容易出現問題。所以,我們在類中應該盡量使用self.a的形式來訪問屬性。
用self.name 是更好的選擇,因為這樣可以相容懶載入,同時也避免了使用下劃線的時候忽視了self這個指標,後者容易在block中造成迴圈引用。同時,使用_是獲取不到父類的屬性,因為它只是對區域性變數的訪問。
OC中self a與 a的用法
person.m inte ce person nsobject property nonatomic,copy nsstring name property nonatomic,copy nsstring void changenamevalue nsstring newname and valu...
OC中instanceType和id的區別
今天在學習oc的過程中遇到關於instancetype和id的問題不太明白。查了一些資料後,總結它們兩個的區別和聯絡主要有以下幾點 相同點 instancetype和id都是作為方法的返回型別而被使用。不同點 1.instancetype可以返回和方法所在類相同型別的物件,id返回的型別只能是未知型...
剖析OC中的bounds與frame的區別
在oc的ui控制項中,我們常常會碰到兩個屬性frame 與bound,前者相對比較好理解,而bound有時候卻比較繞,今天我們來仔細研究下bound的一些特性。首先,我們來看下下面的 通過 我們可以看出bounds的width值 height值與frame是相等的,只不過origin點的x y預設都...