AppDelegate 常看見如下寫法:
常看見: @synthesize window=_window; 意思是說,window 屬性為 _window 實例變量合成訪問器方法。
解析:
意思是說window屬性生成存取方法 :setWindow方法,而這個方法就是實際變量 _window的 的存取方法,setwindow操作的就是_window這個方法。
PS:window是屬性,而_window是實際的變量。
注意:通過這個看似是賦值的這樣一個操作,我們可以在@synthesize 中定義與變量名不相同的getter和setter的命名,籍此來保護變量不會被不恰當的訪問。
常見兩種寫法:
一:
@interface MyClass:NSObject{
MyObjecct *_myObject;
}
@property(nonamtic, retain) MyObjecct *myObject;
@end
@implementatin MyClass
@synthesize myObject=_myObject;
二:
@interface MyClass:NSObject{
}
@property(nonamtic, retain) MyObjecct *myObject;
@end
@implementatin MyClass
@synthesize myObject=_myObject;
這個類中聲明了一個變量_myObject,又聲明了一個屬性叫myObject,然後用@synthesize生成了屬性myObject的存取方法,這個存取方法的名字應該是:setmyObject和getmyObject。@synthesize myObject=_myObject的含義就是屬性myObject的存取方法是做用於_myObject這個變量的。這種用法在Apple的Sample Code中很常見。
從上面我們就應該清楚: 是的,myObject是屬性,而_ myObject才是變量,我們最終操作的變量都是_myObject。
實例解析:
C代碼 1:
self.nameVarPtr = [[ObjectName alloc] init]
C代碼 2:
nameVarPtr = [[ObjectName alloc] init]
解刨:
self.nameVarPtr=xxx 這種賦值方式等價於調用 [self setnameVarPtr:xxx], 而setnameVarPtr:xxx的方法的實現又是依賴於@property的屬性的,比如retain,assign等屬性。
nameVarPtr = xxx 的賦值方式,僅僅是對一個指針進行賦值。nameVarPtr僅僅是一個指針變量,記錄了xxx的地址。在這個過程中不會調用setter方法,不會調用setter方法,就和@property沒有關系,從而,也和retain,assign等屬性沒有關系。這種賦值方式就是一個簡單的指針賦值。
綜上,對成員變量進行賦值,為防內存洩露需要注意的點:
1.self調用setter方法的方式
ObjectName* tmp= [[ObjectName alloc] init];
self.nameVarPtr =tmp; //retainCount=2
[tmp release]; //retainCount=1
2.指針賦值方式,不會調用setter方法
nameVarPtr= [[ObjectName alloc] init]; // retainCount=1
所以: 建議如下 :
大家在對某個變量進行賦值操作的時候,盡量要寫self.myObj = xxx; 這才是最可靠的方法。
@property屬性只是普及 ;
readwrite:這個屬性是默認的情況,會自動為你生成存取器
assign:這個屬性一般用來處理基礎類型,比如int、float等等,如果你聲明的屬性是基礎類型的話,assign是默認的,你可以不加這個屬性
natomic:默認是有該屬性的,這個屬性是為了保證程序在多線程情況,編譯器會自動生成一些互斥加鎖代碼,避免該變量的讀寫不同步問題
readonly:只生成getter不會有setter方法
copy:這個會自動生成你賦值對象的克隆,相當於在內存中新生成了該對象的副本,這樣一來,改變賦值對象就不會改變你聲明的這個成員變量了
retain: 會自動retain賦值對象 指定retain應該在後面的對象上調用,前一個值發送一條release消息。你可以想象一個NSString實例,它是一個對象,而且你可能想要retain它。釋放舊的對象,將舊對象的值賦予輸入對象,再提高輸入對象的索引計數為1 ,使用retain: 對其他NSObject和其子類 ,retain,是說明該屬性在賦值的時候,先release之前的值,然後再賦新值給屬性,引用再加1。
nonatomic:如果該對象無需考慮多線程的情況,請加入這個屬性,這樣會讓編譯器少生成一些互斥加鎖代碼,可以提高效率 保證setter/getter的原子性,多線程情況下數據可能會有問題。nonatomic,非原子性訪問,不加同步,多線程並發訪問會提高性能。
atomic:對於對象的默認屬性,就是setter/getter生成的方法是一個原子操作。如果有多個線程同時調用setter的話,不會出現某一個線程執行setter全部語句之前,另一個線程開始執行setter的情況,相關於方法頭尾加了鎖一樣。