iOS與OS X多線程和內(nèi)存管理(一)內(nèi)存管理

前言

讀完《iOS與OS X多線程和內(nèi)存管理》有一段時(shí)間了,當(dāng)時(shí)是和《Effective Objective-C 2.0 編寫高質(zhì)量iOS與OS X代碼的52個(gè)有效方法 》一起學(xué)習(xí)的,個(gè)人認(rèn)為這兩本書中有很多相輔相成的東西 ,很適合一起學(xué)習(xí),現(xiàn)在有空閑時(shí)間,就想把之前粗略的筆記進(jìn)行一下簡單的整理,主要是書中的內(nèi)容整理和總結(jié),如有理解錯(cuò)誤的地方,希望大家指出,我們一起學(xué)習(xí)和探討~

心得

內(nèi)存管理的內(nèi)容建議先閱讀《iOS與OS X多線程和內(nèi)存管理》中的內(nèi)容,個(gè)人認(rèn)為講解的很詳細(xì)和深入,閱讀完以后建議配合《Effective Objective-C 2.0 編寫高質(zhì)量iOS與OS X代碼的52個(gè)有效方法 》中的內(nèi)存管理再次深入,這只是個(gè)人學(xué)習(xí)上的一點(diǎn)建議,希望對(duì)大家有幫助

內(nèi)容

  • 自己生成的對(duì)象,自己所持有
  • 非自己生成的對(duì)象,自己也能持有
  • 不再需要自己持有的對(duì)象時(shí)釋放
  • 非自己持有的對(duì)象無法釋放
D343490EFA176479A39517E2F1F74686.jpg

cocoa框架中Foundation框架類庫中NSObject類來負(fù)責(zé)內(nèi)存管理

一、自己生成的對(duì)象,自己所持有

使用以下名稱開頭的方法(并且方法名遵守駝峰式拼寫法),‘自己生成的對(duì)象只有自己持有’;調(diào)用該方法的調(diào)用者也意味著‘自己生成并持有對(duì)象’

alloc 
id obj = [[NSObject alloc]init];

new 
id obj = [NSObject new];

copy

mutableCopy

  • 方法名命名實(shí)例:
//下列名稱也意味著自己生成并持有對(duì)象
allocMyObject
newThatObject
copyThis
mutablCopyYourObject
//不屬于同一類別的方法
allocated
newer
copying
mutableCopyed

二、非自己生成的對(duì)象,自己也能持有

使用除alloc、new、copy、mutableCopy以外的方法取得的對(duì)象,因?yàn)榉亲约荷刹⒊钟?,所以自己不是該?duì)象的持有者,但是可以通過retain方法取得對(duì)象的持有權(quán)

id obj = [NSMutableArray array];//取得的對(duì)象存在,但自己不持有對(duì)象
[obj retain];//取得對(duì)象的持有權(quán)

三、不再需要自己持有的對(duì)象時(shí)釋放

注:自己持有的對(duì)象,一旦不再需要,持有者有義務(wù)釋放該對(duì)象,釋放使用release方法

取得對(duì)象的持有權(quán)方式(包含釋放):

/*
 * 通過alloc/new/copy/mutableCopy等方法‘自己生成并持有對(duì)象’
 */

 id obj = [[NSObject alloc] init];//自己持有對(duì)象
[obj release];  //釋放對(duì)象 

/*
 * 通過alloc/new/copy/mutableCopy等開頭的自定義方法‘自己生成并持有對(duì)象’
 */

-(id)allocObject{
     id obj = [[NSObject alloc] init];//自己持有對(duì)象
    return obj;
}

//取得非自己生成并持有對(duì)象
 id obj1 = [obj0 allocObject];//因?yàn)閍llocObject符合命名規(guī)則,所以意味著‘自己生成并持有對(duì)象’
[obj release]; //釋放對(duì)象 
/*
 * 通過alloc/new/copy/mutableCopy等方法以外的方法‘取得非自己生成并持有對(duì)象’
 */
 id obj = [NSMutableArray array];//取得的對(duì)象存在,但自己不持有對(duì)象
[obj retain];//通過retain方法,自己持有對(duì)象  
[obj release]; //釋放對(duì)象 
/*
 * 通過alloc/new/copy/mutableCopy等開頭以外的自定義方法‘取得非自己生成并持有對(duì)象’
 */
-(id)object{
     id obj = [[NSObject alloc] init];//自己持有對(duì)象
    [obj autorelease];//取得的對(duì)象存在,但自己不持有對(duì)象,使用NSMutableArray類的array類方法等可以取得誰都不持有的對(duì)象,同時(shí)通過‘a(chǎn)utorelease實(shí)現(xiàn)的’
    return obj;
}

 id obj1 = [obj0 object];//因?yàn)閛bject不符合命名規(guī)則,所以意味著‘取得的對(duì)象存在,但自己不持有對(duì)象’
[obj1 retain];//也能通過retain方法將調(diào)用autorelease方法取得的對(duì)象變?yōu)樽约撼钟校? 
[obj release];  //釋放對(duì)象 

四、非自己持有的對(duì)象無法釋放

可以并需要釋放對(duì)象的情況

  • 用alloc/new/copy/mutableCopy方法生成并持有的對(duì)象
  • 用retain方法持有的對(duì)象

不可以釋放對(duì)象的情況

  • 自己生成并持有對(duì)象后,在釋放完不再需要的對(duì)象后再次釋放
   id obj = [[NSObject alloc] init];
  [obj release];
  [obj release];
  • 取得的對(duì)象存在,但自己不持有的情況下釋放對(duì)象
  id obj1 = [obj0 object]
  [obj1 release];

五、allco/new/copy/mutableCopy實(shí)現(xiàn)

alloc

id obj =[NSObject alloc]
/*
* alloc方法實(shí)現(xiàn)
* 通過allocWithZone:類方法調(diào)用NSAllocateObject函數(shù)分配了對(duì)象
* NSAllocateObject函數(shù)通過調(diào)用NSZoneMalloc函數(shù)來分配存放對(duì)象所需的內(nèi)存空間,之后將內(nèi)存空間置0,最后返回作為對(duì)象而使用的指針
* 執(zhí)行alloc后對(duì)象的retainCount=1(不考慮其他因素,只執(zhí)行alloc后通過[obj retainCount]方法獲取的值)
*/
+(id)alloc{
   return [self allocWithZone : NSDfaultMallocZone()];
}
+(id) allocWithZone:(NSZone *)z{
 return NSAllocateObject(self , 0 ,z);
}

疑惑點(diǎn)
1、 NSAllocateObject函數(shù)通過調(diào)用NSZoneMalloc函數(shù)來分配存放對(duì)象所需的內(nèi)存空間,之后將內(nèi)存空間置0,最后返回作為對(duì)象而使用的指針

  • 為什么要內(nèi)存空間置0 ?
    • 答:分配存放對(duì)象A所需的內(nèi)存空間,可能之前屬于對(duì)象B并且存放很多B的東西,現(xiàn)在分配給A后,要將內(nèi)存空間置0,防止野指針產(chǎn)生。
  • 知識(shí)點(diǎn)擴(kuò)充:
    • 產(chǎn)生野指針的成因:
      • 1、指針變量未初始化
      • 2、指針釋放后之后未置空
      • 3、指針操作超越變量作用域

總結(jié)

  • a、 在objective-C的對(duì)象中存有引用計(jì)數(shù)這一整數(shù)值
  • b、調(diào)用alloc或是retain方法后,引用計(jì)數(shù)值加1
  • c、調(diào)用release后,引用計(jì)數(shù)值減1
  • d、引用計(jì)數(shù)值為0時(shí),調(diào)用dealloc方法廢棄對(duì)象
  • e、蘋果采用散列表(引用計(jì)數(shù)表)來管理引用計(jì)數(shù)


    D253DA4A-D7C8-4589-8323-3AD3AEDAC06C.png
  • f、引用計(jì)數(shù)表各記錄中存有內(nèi)存塊地址,可以從各個(gè)記錄追溯到各對(duì)象的內(nèi)存塊
    • f-a、有助于調(diào)試,即使出現(xiàn)故障導(dǎo)致對(duì)象占有的內(nèi)存塊損壞,只要引用計(jì)數(shù)表沒有被破壞,就可以確認(rèn)各內(nèi)存塊的位置,另外在利用工具檢測內(nèi)存泄露時(shí),引用計(jì)數(shù)表的各記錄有助于檢測各對(duì)象的持有者是否存在


      D09BA31A-4A1D-4E3F-896B-3A71A964D9E2.png

六、autorelease

  • autorelease會(huì)像C語言的自動(dòng)變量那樣對(duì)待對(duì)象實(shí)例,當(dāng)超出其作用域(NSAutoreleasePool對(duì)象的生存周期)時(shí),對(duì)象實(shí)例的release實(shí)例方法會(huì)被調(diào)用,另外編程人員可設(shè)定變量的作用域

  • autorelease的具體使用方法:

    • (1)生成并持有NSAutoreleasePool對(duì)象
    • (2)調(diào)用已有分配對(duì)象的autorelesae實(shí)例方法
    • (3)廢棄NSAutoreleasePool對(duì)象
5C0271E3-A893-4691-8D09-7AF019CF912B.png
  • 所有調(diào)用autorelease實(shí)例方法的對(duì)象,在廢棄NSAutoreleasePool對(duì)象時(shí),都將調(diào)用release實(shí)例方法(只要不廢棄NSAutoreleasePool對(duì)象,那么生成的對(duì)象就不能被釋放)
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
  id obj = [[NSObject alloc]init];
  [obj release];
  [pool drain];//廢棄NSAutoreleasePool對(duì)象,相當(dāng)于 [obj release];
  • 程序主循環(huán)的NSRunLoop或者在其他程序可運(yùn)行的地方,對(duì)NSAutoreleasePool對(duì)象進(jìn)行生成、持有、廢棄處理


    27529D24-9612-4FB8-8D6C-7C94D84CADCB.png
  • autorelease如何實(shí)現(xiàn)

/*
* autorelease實(shí)例方法的本質(zhì)就是調(diào)用NSAutoreleasePool對(duì)象的addObject類方法
* addObject類方法調(diào)用正在使用的NSAutoreleasePool對(duì)象的addObject實(shí)例方法(如果嵌套生成或持有NSAutoreleasePool對(duì)象,使用最內(nèi)側(cè)的對(duì)象)
* 調(diào)用NSObject類的autorelease實(shí)例方法,該對(duì)象將被追加到正在使用的NSAutoreleasePool對(duì)象中的數(shù)組中
*/
  [obj autorelease];
  
-(id)autorelease{
  [NSAutorelesaePool addObject:self];
}

// addObject類方法:
+(id)addObject:(id) anObj{
  NSAutorelesaePool *pool = 取得正在使用的NSAutorelesaePool對(duì)象;
  if(pool != nil){
      [pool addObject:anObj];
  }else{
     //NSAutorelesaePool對(duì)象非存在狀態(tài)下調(diào)用autorelease;
  }
}

 //NSAutoreleasePool對(duì)象的addObject實(shí)例方法
-(id)addObject:(id)anObj{
   [array addObject: anObj]  ;
 }

//通過drain實(shí)例方法廢棄正在使用的NSAutoreleasePool對(duì)象過程(數(shù)組中所有的對(duì)象都調(diào)用了release實(shí)例方法)
-(void)drain{
    [self dealloc];
}
-(void)dealloc{
    [self emptyPool];
    [array release];
}
-(void) emptyPool{
    for(id obj in array){
        [obj release];
  }
}

總結(jié)

  • 在Cocoa框架中有很多類方法用于返回autorelease的對(duì)象(例如:NSMutableArray類中的arrayWithCapacity類方法)
  id array = [NAMutableArray arrayWithCapacity:1];
  //等同與以下代碼
  id array =[[[NAMutableArray alloc] initWithCapacity:1] autorelease] ;
  • 可通過NSAutoreleasePool類中的非公開類方法showPools來確認(rèn)已被autorelease的對(duì)象的狀況(該函數(shù)在檢查某對(duì)象是否被自動(dòng)release時(shí)非常有用)
  [NSAutorelease showPools];
  • 對(duì)象的autorelease實(shí)例方法,實(shí)現(xiàn)上是調(diào)用的都是NSObject類的autorelease實(shí)例方法

七、ARC規(guī)則

  • 設(shè)置ARC是否有效
    • -fno-objc-arc 無效
    • -fobjc-arc 有效(默認(rèn))

所有權(quán)修飾符

  • OC編程中為了處理對(duì)象,可將變量類型定義為id類型或各種對(duì)象類型

    • 對(duì)象類型:就是指向NSObject這樣的OC類的指針,例如NSObject *
    • id類型:用于隱藏對(duì)象類型的類名部分
    • ARC有效時(shí),id類型和對(duì)象類型上必須附加所有權(quán)修飾符
  • 所有權(quán)修飾符

    • _strong修飾符
    • _weak修飾符
    • _unsafe_unretained修飾符
    • _autoreleaseing修飾符

_strong修飾符

  • _strong修飾符是id類型和對(duì)象類型默認(rèn)的所有權(quán)修飾符
id obj = [[NSObject alloc] init];
//等價(jià)于
id _strong obj = [[NSObject alloc] init];
  • 源代碼ARC無效時(shí)情況
/*
* 情況一
*/
id obj = [[NSObject alloc] init];
//等價(jià)于
id obj = [[NSObject alloc] init];//ARC無效時(shí)

/*
* 情況二
*/
id _strong obj = [[NSObject alloc] init];
//等價(jià)于
id obj = [[NSObject alloc] init];
[obj release];//為了釋放生成并持有的對(duì)象,增加調(diào)用了release方法
  • _strong修飾符表示對(duì)對(duì)象的‘強(qiáng)引用’,附有_strong修飾符的變量obj在超出其變量的作用域時(shí),即在該被變量被廢棄時(shí),隨著強(qiáng)引用的失效,引用的對(duì)象會(huì)隨之釋放
  • _strong修飾符的變量,不僅只在變量的作用域中,在賦值上也可以管理其對(duì)象的所有者
//obj0持有對(duì)象A的強(qiáng)引用
id obj0 = [[NSObject alloc] init];/*對(duì)象A*/
//obj1持有對(duì)象B的強(qiáng)引用
id obj1 = [[NSObject alloc] init];/*對(duì)象B*/
/*
* obj0持有由obj1賦值的對(duì)象B的強(qiáng)引用
* 因?yàn)閛bj0被賦值,所以原先持有的對(duì)對(duì)象A的強(qiáng)引用失效
* 對(duì)象A的持有者不存在,因此廢棄對(duì)象A
* 此時(shí)持有對(duì)象B的強(qiáng)引用的變量為obj0 和obj1
*/
obj0 = obj1;

  • _strong _weak _autorelease修飾符,可以保證將附有這些修飾符的自動(dòng)變量初始化為nil
  • 通過_strong修飾符,不必再次鍵入retain和release
  • 只要通過對(duì)帶有_strong修飾符的變量賦值就可達(dá)成‘自己生成的對(duì)象,自己持有’和‘非自己生成的對(duì)象,自己也能持有’
  • 通過廢棄帶_strong修飾符的變量(變量作用域結(jié)束、成員變量所屬對(duì)象廢棄)或者對(duì)變量賦值,都可達(dá)到‘不在需要自己持有的對(duì)象時(shí)釋放’

_weak修飾符

  • 循環(huán)引用:就是應(yīng)當(dāng)廢棄的對(duì)象在超出其生命周期后繼續(xù)存在,循環(huán)引用容易發(fā)生內(nèi)存泄露
{
//test0持有Test對(duì)象A的強(qiáng)引用
id test0 =[[Test alloc] init];/*對(duì)象A*/
//test1持有Test對(duì)象B的強(qiáng)引用
id test1 =[[Test alloc] init];/*對(duì)象A*/
/*
* Test對(duì)象A的obj_成員變量持有Test對(duì)象B的強(qiáng)引用
* 此時(shí)持有Test對(duì)象B的強(qiáng)引用變量為test1、Test對(duì)象A的obj_
*/
[test0 setObject: test1];

/*
* Test對(duì)象B的obj_成員變量持有Test對(duì)象A的強(qiáng)引用
* 此時(shí)持有Test對(duì)象A的強(qiáng)引用變量為test0、Test對(duì)象B的obj_
*/
[test1 setObject: test0];
}
/*
* 因?yàn)閠est0變量超出其作用域,強(qiáng)引用失效,自動(dòng)釋放Test對(duì)象A
* 因?yàn)閠est1變量超出其作用域,強(qiáng)引用失效,自動(dòng)釋放Test對(duì)象B
* 此時(shí)持有Test對(duì)象B的強(qiáng)引用變量為Test對(duì)象A的obj_
* 此時(shí)持有Test對(duì)象A的強(qiáng)引用變量為Test對(duì)象B的obj_
* 內(nèi)存泄露
*/

  • _weak修飾符于_strong修飾符相反,提供弱引用,弱引用不能持有對(duì)象實(shí)例
  • 將自己生成并持有的對(duì)象賦值為附有_weak修飾符的變量,因?yàn)槿跻貌荒艹钟袑?duì)象,在超出其變量的作用域時(shí),對(duì)象就沒有了持有者,所以廢棄該對(duì)象
  • _weak修飾符,在持有某對(duì)象的弱引用時(shí),若該對(duì)象被廢棄,則此弱引用將自動(dòng)失效且處于nil被賦值的狀態(tài)
  • _weak修飾符可避免循環(huán)引用,通過檢查 _weak修飾符的變量是否為nil,可以判斷被賦值的對(duì)象是否已廢棄

_unsafe_unretained修飾符

  • 盡管ARC式的內(nèi)存管理時(shí)編譯器的工作,但附有_unsafe_unretained修飾符的變量不屬于編譯器內(nèi)存管理對(duì)象

_autorelease修飾符

  • ARC有效時(shí)不能使用autorelease方法,也不能使用NSAutoreleasePool類
  • ARC有效時(shí),通過將對(duì)象賦值給附有_autorelease修飾符的變量來代替調(diào)用autorelease方法,將對(duì)象注冊到autoreleasepool
  • 非顯示使用_autorelease修飾符
    • 編譯器檢查方法名是否已a(bǔ)lloc/new/copy/mutableCopy開始,如果不是則自動(dòng)將返回值的對(duì)象注冊到autoreleasepool(init方法返回值的對(duì)象不注冊到autoreleasepool)
    • 在使用_weak修飾符的變量時(shí)就必然要使用注冊到autoreleasepool中的對(duì)象
    • id的指針或?qū)ο蟮闹羔樤跊]有顯示指定時(shí)會(huì)被附加_autorelease修飾符(id * 類型 默認(rèn)為‘id _autorelease ’* 類型)
  • 賦值給對(duì)象指針時(shí),所有權(quán)修飾符必須一致
  • NSRunLOop等實(shí)現(xiàn)無論ARC有效還是無效,均能隨時(shí)釋放注冊到main函數(shù)中autoreleasepool中的對(duì)象
ARC規(guī)則
  • 不能使用retain/release/retainCount/autorelease
  • 不能使用NSAllocateObject/NSDeallocateObject
  • 必須遵守內(nèi)存管理的命名規(guī)則
  • 不能顯示調(diào)用dealloc
  • 使用@autorelease塊代替NSAutoreleasePool
  • 不能使用區(qū)域(NSZone)
  • 對(duì)象型變量不能作為C語言結(jié)構(gòu)體(struct/union)的成員
  • 顯示轉(zhuǎn)化‘id’和‘void’

1、不能使用retain/release/retainCount/autorelease

  • 設(shè)置ARC有效時(shí),禁止再次鍵入retain/release代碼
  • retainCount獲取的值不準(zhǔn)確 ,不建議使用

2、不能使用NSAllocateObject/NSDeallocateObject

  • 會(huì)引起編譯錯(cuò)誤(同retain/release)

3、必須遵守內(nèi)存管理的命名規(guī)則

  • ARC有效時(shí)追加一天命名規(guī)則init(駝峰式)
    • 已init開頭的方法,該方法必須時(shí)‘實(shí)例方法’
    • 并且必須要返回對(duì)象
    • 返回的對(duì)象應(yīng)為id類型或該方法聲明的對(duì)象類型,抑或是該類的超類型或子類型
    • 返回對(duì)象并不注冊到autoreleasepool上
    • 基本上只是對(duì)alloc方法返回的對(duì)象進(jìn)行初始化處理并返回該對(duì)象

4、不能顯示調(diào)用dealloc

  • 無論ARC是否有效,只要對(duì)象的所有者都不持有該歇對(duì)象,該對(duì)象就被廢棄,對(duì)象廢棄,不管ARC是否有效,都會(huì)調(diào)用dealloc方法
  • ARC有效不能顯示調(diào)用dealloc
//ARC無效時(shí)
-(void)dealloc{
    [super dealloc];
}
//ARC有效時(shí)(ARC會(huì)自動(dòng)處理,ARC有效不能顯示調(diào)用dealloc所以不必書寫 [super dealloc])
-(void)dealloc{
 
}
  • dealloc方法在大多數(shù)情況下還適用于刪除已注冊的代理或者觀察者對(duì)象
-(void)dealloc{
   [ [NSNotificationCenter defaultCenter] removeObserver:self];
}

八、屬性

  • 當(dāng)ARC有效時(shí),OC類的屬性也發(fā)生變化
@property (nonatomic , strong) NSString * name;
F7DC6FC7-543A-4E23-9673-9294EA918EF5.png
  • copy屬性不是簡單的賦值,它賦值的是通過NSCopying接口的copyWithZone:方法復(fù)制的復(fù)制源所生成的對(duì)象
  • 在聲明類成員變量時(shí),如果同屬性聲明中的屬性不一致則會(huì)引起編譯錯(cuò)誤
/*
*錯(cuò)誤舉例
*/
/聲明id型obj成員變量
id obj;

//定義其屬性聲明為weak
@property (nonatomic , weak) id obj;

/*
*正確舉例1
*/
/聲明id型obj成員變量
id   _weak obj;

//定義其屬性聲明為weak
@property (nonatomic , weak) id obj;


/*
*正確舉例2
*/

//聲明id型obj成員變量
id  obj;

//定義其屬性聲明為strong
@property (nonatomic , strong) id obj;

九、數(shù)組

  • 除_unsafe_unretained修飾符以外, _strong修飾符、 _weak修飾符、 _autorelease修飾符保證其指定的變量,數(shù)組初始化為nil

十、ARC實(shí)現(xiàn)

_strong修飾符

  • 自己生成并持有對(duì)象
    • 通過兩次調(diào)用objc_msgSend方法(alloc方法、init方法),變量作用域結(jié)束時(shí)通過調(diào)用objc_release釋放對(duì)象
  • 非自己生成,自己持有對(duì)象
    • objc_retainAutoreleasedReturnValue函數(shù):自己持有對(duì)象函數(shù)(持有的對(duì)象應(yīng)為返回注冊在autoreleasepool中的對(duì)象方法或函數(shù)返回值)


      CFA44A73-0A3C-4428-A455-2E0419676574.png

_weak修飾符

  • 附有_weak修飾符的變量,通過objc_initWeak函數(shù)初始化,將對(duì)象賦值給該變量,會(huì)將對(duì)象的作為參數(shù)調(diào)用objc_storeWeak函數(shù),objc_storeWeak函數(shù)將對(duì)象的地址作為鍵值,對(duì)應(yīng)變量的地址注冊到weak表中,并且一個(gè)對(duì)象可同時(shí)賦值給多個(gè)_weak修飾的變量,所以一個(gè)鍵值,可以注冊多個(gè)變量地址,對(duì)象釋放時(shí)時(shí)最后調(diào)用的objc_clear_deallocting函數(shù)會(huì)從weak表中獲取廢棄對(duì)象的地址為鍵值的記錄,將包含在記錄中的所有附有_weak修飾符變量的地址,賦值為nil,從weak表中刪除該記錄,從引用計(jì)數(shù)表中刪除廢棄對(duì)象的地址為鍵值的記錄 。

  • 若附有_weakk修飾符的變量所引用的對(duì)象被廢棄,則將nil賦值給該變量

    • 釋放對(duì)象時(shí),廢棄誰都不持有的對(duì)象的同時(shí),有如下操作(詳情見《iOS與os x多線程和內(nèi)存管理》1.4.2 _weak修飾符 p68):
      • 1、objc_release
      • 2、因?yàn)橐糜?jì)數(shù)為0,所以執(zhí)行dealloc
      • 3、_objc_rootDealloc(不知道)
      • 4、objc_dispose(不知道)
      • 5、objc_destructInstance(不知道)
      • 6、objc_clear_deallocting(了解)
    • 對(duì)象被廢棄時(shí)最后調(diào)用的objc_clear_deallocting函數(shù)操作如下:
      • 1、從weak表中獲取廢棄對(duì)象的地址為鍵值的記錄
      • 2、將包含在記錄中的所有附有_weak修飾符變量的地址,賦值為nil
      • 3、從weak表中刪除該記錄
      • 4、從引用計(jì)數(shù)表中刪除廢棄對(duì)象的地址為鍵值的記錄
  • 使用附有_weak修飾符的變量,即是使用注冊到autoreleasepool中的對(duì)象

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容