@property還有一些關鍵字,它們都是有特殊做用的,好比上述代碼中的nonatomic,strong:安全
@property(nonatomic,strong) NSString *carName;多線程
@property(nonatomic,strong) NSString *carType;atom
我把它們分爲三類,分別是:原子性,存取器控制,內存管理。線程
原子性對象
atomic(默認):atomic意爲操做是原子的,意味着只有一個線程訪問實例變量。atomic是線程安全的,至少在當前的存取器上是安全的。它是一個默認的特性,可是不多使用,由於比較影響效率,這跟ARM平臺和內部鎖機制有關。內存
nonatomic:nonatomic跟atomic恰好相反。表示非原子的,能夠被多個線程訪問。它的效率比atomic快。但不能保證在多線程環境下的安全性,在單線程和明確只有一個線程訪問的狀況下普遍使用。get
存取器控制it
readwrite(默認):readwrite是默認值,表示該屬性同時擁有setter和getter。內存管理
readonly: readonly表示只有getter沒有setter。效率
有時候爲了語意更明確可能須要自定義訪問器的名字:
@property (nonatomic, setter = mySetter:,getter = myGetter ) NSString *name;
最多見的是BOOL類型,好比標識View是否隱藏的屬性hidden。能夠這樣聲明:
@property (nonatomic,getter = isHidden ) BOOL hidden;
內存管理
@property有顯示的內存管理策略。這使得咱們只須要看一眼@property聲明就明白它會怎樣對待傳入的值。
assign(默認):assign用於值類型,如int、float、double和NSInteger,CGFloat等表示單純的複製。還包括不存在全部權關係的對象,好比常見的delegate。
@property(nonatomic) int running;
@property(nonatomic,assign) int running;
以上兩段代碼是相同的。
在setter方法中,採用直接賦值來實現設值操做:
-(void)setRunning:(int)newRunning{
_running = newRunning;
}
retian:在setter方法中,須要對傳入的對象進行引用計數加1的操做。
簡單來講,就是對傳入的對象擁有全部權,只要對該對象擁有全部權,該對象就不會被釋放。以下代碼所示:
-(void)setName:(NSString*)_name{
//首先判斷是否與舊對象一致,若是不一致進行賦值。
//由於若是是一個對象的話,進行if內的代碼會形成一個極端的狀況:當此name的retain爲1時,使這次的set操做讓實例name提早釋放,而達不到賦值目的。
if ( name != _name){
[name release];
name = [_name retain];
}
}
strong:strong是在IOS引入ARC的時候引入的關鍵字,是retain的一個可選的替代。表示實例變量對傳入的對象要有全部權關係,即強引用。strong跟retain的意思相同併產生相同的代碼,可是語意上更好更能體現對象的關係。
weak:在setter方法中,須要對傳入的對象不進行引用計數加1的操做。
簡單來講,就是對傳入的對象沒有全部權,當該對象引用計數爲0時,即該對象被釋放後,用weak聲明的實例變量指向nil,即實例變量的值爲0。
注:weak關鍵字是IOS5引入的,IOS5以前是不能使用該關鍵字的。delegate 和 Outlet 通常用weak來聲明。
copy:與strong相似,但區別在於實例變量是對傳入對象的副本擁有全部權,而非對象自己。