1,ARC的本質(zhì)
為武寧等地區(qū)用戶提供了全套網(wǎng)頁(yè)設(shè)計(jì)制作服務(wù),及武寧網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站、成都外貿(mào)網(wǎng)站建設(shè)公司、武寧網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!ARC本質(zhì)是NSAutoreleasePool的直接應(yīng)用,
@autorelease{
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
其實(shí)是:
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
int iRet = UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
[pool release];
然后,各種allocrelease后,對(duì)應(yīng)refcount都設(shè)置成0,在出自己的引用范圍后,就背nsautoreleasepool自動(dòng)的釋放掉,如下:
NSString* str = [[[NSString alloc] init] autorelease];
.......
其中str已經(jīng)進(jìn)行了autorelease,當(dāng)結(jié)束生命周期后,str直接釋放掉。
2,NSAutoreleasePool的原理
AutoreleasePoolPage是一個(gè)C++實(shí)現(xiàn)的類。
typedef struct{magic_t const magic;id* next;pThread_t* thread;AutoreleasePoolPage* Parent;AutoreleasePoolPage* Child;uint32_t const depth;uint32_t hiwat;}其中:1,magic是魔術(shù)數(shù)字,劃分內(nèi)存邊界,數(shù)據(jù)結(jié)構(gòu)起始處;2,next,是指向該AutoreleasePool的邊界;3,thread, 是該AutoreleasePool的線程,每個(gè)線程有自己的AutoreleasePool; 4,Parent、child,用于建立鏈表,一個(gè)AutoreleasePool不一定足夠; 每個(gè)NSAutoreleasePool都是4096bytes,不夠的就申請(qǐng)新的NSAutoreleasePool,用child, parent連接起來(lái),見上圖: 1,“類實(shí)例所占內(nèi)存”就是數(shù)據(jù)接口NSAutoreleasePool的空間; 2,“id objx”, 就是各個(gè)申請(qǐng)的對(duì)象指針; 3,next,指的是堆棧頂處; 對(duì)象是如何申請(qǐng)的?圖中的情況,這一頁(yè)再加入一個(gè)autorelease對(duì)象就要滿了(也就是next指針馬上指向棧頂),這時(shí)就要執(zhí)行上面說(shuō)的操作,建立下一頁(yè)page對(duì)象,與這一頁(yè)鏈表連接完成后,新page的next指針被初始化在棧底(begin的位置),然后繼續(xù)向棧頂添加新對(duì)象。
所以,向一個(gè)對(duì)象發(fā)送- autorelease消息,就是將這個(gè)對(duì)象加入到當(dāng)前AutoreleasePoolPage的棧頂next指針指向的位置
對(duì)象是如何釋放的? 每當(dāng)進(jìn)行一次objc_autoreleasePoolPush調(diào)用時(shí),runtime向當(dāng)前的AutoreleasePoolPage中add進(jìn)一個(gè)哨兵對(duì)象,值為0(也就是個(gè)nil),那么這一個(gè)page就變成了下面的樣子:objc_autoreleasePoolPush的返回值正是這個(gè)哨兵對(duì)象的地址,被objc_autoreleasePoolPop(哨兵對(duì)象)作為入?yún)?,于是?/p>
1.根據(jù)傳入的哨兵對(duì)象地址找到哨兵對(duì)象所處的page
2.在當(dāng)前page中,將晚于哨兵對(duì)象插入的所有autorelease對(duì)象都發(fā)送一次- release消息,并向回移動(dòng)next指針到正確位置
3.補(bǔ)充2:從最新加入的對(duì)象一直向前清理,可以向前跨越若干個(gè)page,直到哨兵所在的page
剛才的objc_autoreleasePoolPop執(zhí)行后,最終變成了下面的樣子:
嵌套的AutoreleasePool
知道了上面的原理,嵌套的AutoreleasePool就非常簡(jiǎn)單了,pop的時(shí)候總會(huì)釋放到上次push的位置為止,多層的pool就是多個(gè)哨兵對(duì)象而已,就像剝洋蔥一樣,每次一層,互不影響。