一、修飾 @property 的特性類型:
1、assign:
(1)、一般用來修飾基本的數(shù)據(jù)類型(例:NSInteger,CGFloat,int,char等等);
(2)、引用計(jì)數(shù):不會(huì)增加,屬性釋放后就沒有了;
(3)、內(nèi)存分配:棧上,由系統(tǒng)自動(dòng)處理,不會(huì)造成野指針;
(4)、是否可以用它修飾對(duì)象類型呢?(比如:NSArray、NSDictionary等等)?
答:修飾是可以的,但是這樣屬性釋放后會(huì)造成野指針,后續(xù)被其他對(duì)象引用時(shí)就會(huì)產(chǎn)生crash現(xiàn)象。
2、retain:
(1)、用來修飾對(duì)象(NSObject)類型(例:NSArray、NSDictionary等等);
(2)、引用計(jì)數(shù):引用時(shí)+1,釋放時(shí)-1,只有當(dāng)引用計(jì)數(shù)為0時(shí),就會(huì)被dealloc函數(shù)回收內(nèi)存;
(3)、內(nèi)存分配:堆上,(alloc,new),由編程者手動(dòng)釋放,但在ARC環(huán)境下由編譯器自動(dòng)檢測(cè)管理,最后在引用計(jì)數(shù)為0時(shí),就會(huì)被dealloc函數(shù)回收內(nèi)存。
3、copy:
(1)、一般用來修飾NSString(NSMutableString),NSDictionary(NSMutableDictionary)等等(其對(duì)應(yīng)有可變類型的子類),還有block;
(2)、引用計(jì)數(shù):同retain;
(3)、內(nèi)存分配:同retain;
(4)、與retain的區(qū)別:retain的引用是拷貝指針地址(淺拷貝),而copy是拷貝對(duì)象本身(深拷貝),重新分配地址;當(dāng)修改對(duì)象值時(shí),淺拷貝會(huì)改變?cè)贾?,而深拷貝不?huì)。由于NSString與NSMutableString之間有可能進(jìn)行賦值操作,為了防止內(nèi)容被修改,因此使用copy去深拷貝一份。
4、weak:
(1)、即弱引用,類似于assign,一般用在防止循環(huán)引用的情景下(例:父類引用了子類,子類引用了父類);還用在IBOutlet、delegate(代理),由于它們會(huì)在類外部被調(diào)用,防止循環(huán)引用;
(2)、引用計(jì)數(shù):不會(huì)增加,引用計(jì)數(shù)為0時(shí),對(duì)象釋放后自動(dòng)置nil,不會(huì)造成野指針;
(3)、內(nèi)存分配:堆上(對(duì)象申請(qǐng)內(nèi)存地址都在堆上);
(4)、與assign的區(qū)別:當(dāng)使用assign修飾對(duì)象的時(shí),雖然引用計(jì)數(shù)不會(huì)增加,但是對(duì)象釋放時(shí)會(huì)造成野指針,后續(xù)對(duì)象申請(qǐng)內(nèi)存空間時(shí),剛好使用當(dāng)該內(nèi)存地址就會(huì)造成crash異常,所以最好不要使用assign修飾對(duì)象。
5、strong:
(1)、即強(qiáng)引用,類似于retain,一般需要持有此對(duì)象的情景下(例:類內(nèi)部的屬性),若不是屬性,則在初始化對(duì)象時(shí),編譯器會(huì)自動(dòng)加上 __strong修飾;
(2)、引用計(jì)數(shù):同retain,也會(huì)增加;
(3)、內(nèi)存分配:堆上;
(4)、與retain的區(qū)別:一般情況下是一樣的,但在修飾block的時(shí)是不一樣的,strong會(huì)等價(jià)于copy;而retain居然等價(jià)于assign,內(nèi)存分配在棧上,會(huì)造成野指針引起crash(BAD_ACCESS);因此,block最好使用copy修飾。
6、nonatomic:
(1)、即非原子性,不是默認(rèn)的;更快;如有兩個(gè)線程訪問同一個(gè)屬性,會(huì)出現(xiàn)無法預(yù)料的結(jié)果;非線程安全,適合內(nèi)存較小的移動(dòng)設(shè)備。
7、atomic:
(1)、即原子性,是默認(rèn)的;對(duì)同一對(duì)象的set和get的操作是順序執(zhí)行的;速度不快,因?yàn)橐WC操作整體完成;(讀/寫)線程安全,需要消耗大量系統(tǒng)資源來為屬性加鎖;系統(tǒng)生成的 getter/setter 會(huì)保證 get、set 操作的完整性,不受其他線程影響,而該屬性在其他多個(gè)線程調(diào)用,并不保證線程安全,需要開發(fā)者自行處理。
8、readonly:
(1)、只讀,只有g(shù)et方法,不被外部改變時(shí)使用。
9、readwrite:
(1)、讀寫,有set、get方法。
注:屬性沒有顯式修飾,則默認(rèn)readwrite。
10、getter=XXX:
(1)、XXX表示get方法名;例:
@property (assign, nonatomic, getter=isDidSelected) BOOL didSelected;