先介紹指針相關(guān)的幾個概念(看有的書上介紹下面的未初始化的叫野指針,野指針叫懸空指針煮岁,可能和其它平臺理解有所差異凄硼,但是iOS這邊大家理解的應(yīng)該是下面介紹的這種,如有錯誤請幫忙指出尉间,謝謝!轉(zhuǎn)載請注明出處击罪,喜歡的話哲嘲,請點個贊吧!)
1媳禁、未初始化指針眠副。eg:Person *a;
2竣稽、空指針囱怕,沒有存儲任何內(nèi)存地址的指針就稱為空指針也就是nil霍弹,NULL。eg:Person *a = nil/NULL;(nil是OC對象類型的空指針娃弓,NULL是C類型的空指針)
3典格、野指針,指向的對象內(nèi)存被釋放台丛,但是指針沒有讓其變?yōu)榭罩羔標=桑廊贿€指向那塊內(nèi)存,如果再向其發(fā)消息就會crash挽霉。eg:
Person *a = [Person new]防嗡;
[a release];
[a setName:@"小明"]炼吴;
/// 正確做法是在release后加一句 a = nil本鸣;舉例為了直觀方便使用了release方法代表
Person *a = [Person new];
[a release]硅蹦;
a = nil;
[a setName:@"小明"]荣德;
/// 這樣最后一句向nil發(fā)消息雖然無效但是不會crash
4、僵尸對象童芹,被釋放的對象比如上面的a所指向的對象執(zhí)行了release涮瞻,那么對象的內(nèi)存還未被重新分配的時候,這個對象其實還能被訪問因為內(nèi)存還存在假褪,這個時候就被稱之為僵尸對象署咽。
一、含義
1生音、assign
assign主要用來修飾基本數(shù)據(jù)類型宁否,例如int,float缀遍,NSInteger慕匠,CGFloat,儲存在棧中內(nèi)存不需要管理域醇,一般不修飾對象台谊,不然對象內(nèi)存地址被釋放,但是指針不會釋放就會造成野指針譬挚。
2锅铅、weak
weak只能用來修飾對象,但是并不持有减宣,引用計數(shù)不會+1盐须。在Runtime中對該屬性進行了操作,指向的內(nèi)存被釋放后(引用計數(shù)為0)漆腌,指針就會自動=nil丰歌,多用于避免循環(huán)引用的地方姨蟋。weak原理
3、strong立帖,retain
strong用來修飾對象并持有,引用計數(shù)會+1悠砚,正常情況指向的對象不會被銷毀晓勇,可以手動置為空指針來減少引用計數(shù),引用計數(shù)為0則銷毀對象灌旧,ARC下的strong相當于MRC下的retain(ARC用retain效果和strong一樣)绑咱。
4、copy
和strong類似枢泰,如果對象里面沒有支持NSCopying協(xié)議執(zhí)行copyWithZone方法描融,那和strong效果基本一樣,對象引用計數(shù)會+1衡蚂,不拷貝新的對象出來窿克。反之,copy所指向的是一個拷貝出來新的對象毛甲,引用計數(shù)為1年叮,多半用于修飾可變類型的不可變對象NSString,NSDictionary玻募,NSArray只损。copy之深淺拷貝詳解
5、unsafe_unretained
unsafe_retain類似weak一樣七咧,不過內(nèi)存如果被釋放了跃惫,指針依舊保存著之前的地址,變成野指針了艾栋,訪問就會crash爆存,所以他是不安全的。
6裹粤、__autoreleasing
在 ARC 模式下终蒂,我們不能顯示的使用 autorelease 方法了,但是 autorelease 的機制還是有效的遥诉,通過將對象賦給 __autoreleasing 修飾的變量就能達到在 MRC 模式下調(diào)用對象的 autorelease 方法同樣的效果拇泣。__autoreleasing 修飾的對象會被注冊到 Autorelease Pool 中,并在 Autorelease Pool 銷毀時被釋放矮锈。
注意:定義 property 時不能使用這個修飾符霉翔,因為任何一個對象的 property 都不應(yīng)該是 autorelease 類型的。__autoreleasing 詳解-文章還未寫
二苞笨、代碼解釋
總結(jié)
1债朵、weak后student引用計數(shù) = 1
2子眶、strong后student引用計數(shù)+1 = 2
3、retain后student引用計數(shù)+1 = 3
4序芦、copy后student引用計數(shù)+1 = 4 // 沒有實現(xiàn)copyWithZone方法臭杰,不然引用計數(shù)不變還是3,但是cyStu所指向的對象不是student了谚中。