nonatomic:非原子性訪問,對屬性賦值的時候不加鎖,多線程並發訪問會提高效能。如果不加此屬性,則預設是兩個存取方法都為原子型事務訪問。
(atomic是Objc使用的一種線程保護技術,基本上來講,是防止在寫未完成的時候被另外一個線程讀取,造成資料錯誤。而這種機制是耗費系統資源的,所 以在iPhone這種小型裝置上,如果沒有使用多線程間的通訊編程,那麼nonatomic是一個非常好的選擇。)
assign: 簡單賦值,不更改索引計數
對基礎資料類型 (例如NSInteger)和C資料類型(int, float, double, char, 等) 適用單一資料型別
copy:建立一個索引計數為1的對象,然後釋放舊對象對NSString
retain:釋放舊的對象,將舊對象的值賦予輸入對象,再提高輸入對象的索引計數為1
對其他NSObject和其子類
//——————————————————————————
看了這麼多也許大家有點暈, 現在進行實際的代碼示範:
@property (nonatomic, assign) int number;
這裡定義了一個int類型的屬性, 那麼這個int是單一資料型別,本身可以認為就是原子訪問,所以用nonatomic, 不需要進行引用計數,所以用assign。 適用於所有單一資料型別。
@property (nonatomic, copy) NSString * myString;
這裡定義了一個NSString類型的屬性,不需要原子操作,所以用nonatomic.
為什麼需要copy,而不是retain呢! 因為如果對myString賦值原字串是一個可變的字串(NSMutableString)對象的話,用retain的話,當原字串改變的時候你的myString屬性也會跟著變掉。我想你不希望看到這個現象。 實際上博主測試, 如果原來的字串是NSString的話,也只是retain一下,並不會copy副本
@property (nonatomic, retain) UIView * myView;
這裡定義了一個UIView類型的屬性,不需要原子操作,所以用nonatomic.
當對myView 賦值的時候原來的UIView對象retainCount會加1
//介面檔案
@interface MyClass : NSObject
@property (nonatomic, assign) int number;
@property (nonatomic, copy) NSString * myString;
@property (nonatomic, retain) UIView * myView;
@end
//實現檔案
@implementation MyClass
@synthesize number;
@synthesize myString;
@synthesize myView;
//釋放記憶體
-(void) dealloc
{
[myString release]; //copy的屬性需要release;
[myView release]; //retain的屬性需要release;
[super dealloc]; //傳回父物件
}
@end
假如你有一段代碼建立了一個MyClass對象
MyClass * instance = [MyClass alloc] init];
//number賦值,沒什麼可說的, 單一資料型別就這樣
instance.number = 1;
//建立一個可變字串
NSMutableString * string = [NSMutableString stringWithString:@"hello"];
instance.myString = string; //對myString賦值
[string appendString:@" world!"]; //往string追加文本
NSLog(@”%@”,string); //此處string已經改變, 輸出為 “hello world!”
NSLog(@”%@”,instance.myString); //輸出myString,你會發現此處輸出仍然為 “hello” 因為 myString在string改變之前已經copy了一份副本
UIView * view = [[UIView alloc] init];
NSLog(@”retainCount = %d”,view.retainCount);
//輸出view的引用計數, 此時為1
instance.myView = view; //對myView屬性賦值
NSLog(@”retainCount = %d”,view.retainCount);
//再次輸出view的引用計數, 此時為2,因為myView對view進行了一次retain。
[view release];
//此處雖然view被release釋放掉了,但myView對view進行了一次retain,那麼myView保留的UIView的對象指標仍然有效。
[instance release] ;