iOS開發(fā)中屬性修飾符基本上每天都會打交道,網(wǎng)上總結(jié)也很多,本文按照實(shí)際開發(fā)的角度簡單介紹一下屬性修飾符,屬性修飾符分為四類,指定方法名,讀寫屬性,賦值的選項(xiàng)和原子性操作.
指定方法名
指定方法名就是自定義getter和setter方法,自定義getter和setter方法之后就不會調(diào)用系統(tǒng)生成的方法,Bool類型屬性自定義getter和setter情況比較常見.
@property (assign, getter=isSuccess,setter=setIsSuccess:,nonatomic) BOOL success;
- (BOOL)isSuccess {
return true;
}
- (void)setIsSuccess:(BOOL)status {
NSLog(@"設(shè)置");
}
讀寫屬性
讀寫屬性修飾符只有readwrite和readonly兩種修飾符,readwrite是默認(rèn)修飾符,系統(tǒng)會生成這個屬性的setter和getter方法以及下劃線開頭的成員變量.
readonly只能讀不能寫,生成一個getter方法下劃線開頭的成員變量,不會創(chuàng)建setter方法,直接進(jìn)行賦值操作系統(tǒng)會報錯.
參考代碼:
@property (strong, readonly,nonatomic) Person *person;
@property (copy, readonly,nonatomic) NSString *name;
賦值屬性
賦值屬性是包含屬性修飾符最多,也是最容易出現(xiàn)問題的地方,賦值屬性修飾符包括assign,unsafe_unretained,retain,strong,weak和copy.如果不指定賦值修飾符,系統(tǒng)默認(rèn)的修飾符是assign.
assign:簡單賦值,不更改引用計(jì)數(shù),用于修飾基礎(chǔ)類型的數(shù)據(jù)(NSInteger)和C語言類型數(shù)據(jù)(int,float,double,char,bool).
unsafe_unretained:其實(shí)質(zhì)等同于assign.
copy: 拷貝傳入的對象(即創(chuàng)建一個引用計(jì)數(shù)為1的新對象,但是內(nèi)容與傳入對象相同),并把新對象賦值給實(shí)例變量.
retain: 釋放舊對象,保留傳入的對象,并使傳入的新對象引用計(jì)數(shù)+1.
strong: 強(qiáng)引用,類似于retain,兩者的區(qū)別在于修飾Block是的如果使用strong修飾,與copy修飾的結(jié)果一樣,如果使用retain修飾Block相當(dāng)于assign.
@property (retain, nonatomic) TestBlock retainBlock;
系統(tǒng)會有有警告提示:
@property (retain, nonatomic) TestBlock retainBlock;
如果使用assign修飾Block,函數(shù)作用域執(zhí)行完之后Block就會失效,進(jìn)行調(diào)用會直接崩潰,使用retain只有一定情況下會崩潰,Block建議使用copy修飾.
weak: 弱引用,不保留傳入的值也不會增加對象的應(yīng)用計(jì)數(shù).類似于assign,但與assign不同的是,當(dāng)它們指向的對象被釋放后,weak會被自動置為nil,而assign則不會,所以assign會導(dǎo)致“野指針”的出現(xiàn),weak可以避免懸空指針.delegate建議使用weak修飾.
原子性修飾符
原子性操作符只有atomic和nonatomic兩種修飾符,系統(tǒng)默認(rèn)的修飾符是atomic.
atomic屬性是為了保證程序在多線程情況下,編譯器會自動生成一些互斥加鎖代碼,避免該變量的讀寫不同步問題.
nonatomic屬性無需考慮多線程的情況,會讓編譯器少生成一些互斥加鎖代碼,可以提高效率.
實(shí)現(xiàn)nonatomic修飾的屬性的getter和setter大家都輕車熟路,如果實(shí)現(xiàn)一個atomic修飾的屬性呢?
@property (copy, atomic) NSString *atomicName;
atomic的getter/setter實(shí)現(xiàn):
@synthesize atomicName = _atomicName;
- (NSString *)atomicName {
NSString *name;
@synchronized (self) {
name = _atomicName;
}
return name;
}
- (void)setAtomicName:(NSString *)atomicName {
@synchronized(self) { //加鎖同步
if (![_atomicName isEqualToString:atomicName]) {
_atomicName = atomicName;
}
}
}
參考資料:
[https://stackoverflow.com/questions/3227176/error-writable-atomic-property-cannot-pair-a-synthesized-setter-getter-with-a-u](https://stackoverflow.com/questions/3227176/error-writable-atomic-property-cannot-pair-a-synthesized-setter-getter-with-a-u)