iOS全解1-1:基礎(chǔ)/內(nèi)存管理RAC撵彻、Block、GCD與多線程

面試系列:


基本概念

一纵隔、OC的三大特性為:封裝翻诉、繼承多態(tài)

1捌刮、封裝:
  • 變量 的封裝:setter碰煌、getter 方法,self調(diào)用方便高效
  • 方法 的封裝:簡潔绅作、高效芦圾,不用關(guān)心內(nèi)部過程
  • SDK 的封裝:使用方便、私有隱藏棚蓄,安全性高(不會泄露數(shù)據(jù)和代碼)
2堕扶、繼承
  • 抽取了重復代碼:子類可以擁有父類中的所有成員變量和方法
  • 建立了類與類之間的聯(lián)系
  • 每個類中都有一個superclass指針指向父類
  • 所有類的根類都是NSObject,便于isa指針 查詢
    • 調(diào)用某個對象的方法時梭依,優(yōu)先去當前類中找,如果找不到典尾,再去父類中找
    • 子類重新實現(xiàn)父類的某個方法役拴,會覆蓋父類以前的方法。

繼承的缺點:耦合性太高(類與類之間的關(guān)系過于緊密)钾埂,沒有多繼承河闰,OC里面都是單繼承科平,多繼承可以用protocol委托代理來模擬實現(xiàn);可以通過實現(xiàn)多個接口完成OC的多重繼承姜性。(實現(xiàn)多個協(xié)議)

3瞪慧、多態(tài)

例如: -(void) animal:(id); id 就是多態(tài),傳入時部念,才識別 具體類的真實形象弃酌。runtime 也是運行時,才識別具體類儡炼。

  1. 要想使用多態(tài)必須使用繼承(繼承是多態(tài)的前提)

  2. 多態(tài):父類指針指向子類對象 Animal *aa = [Dog new]; 調(diào)用方法時會檢測對象的真實形象

  3. 好處:如果函數(shù)或方法參數(shù)中使用的是父類類型妓湘,可以傳入父類,子類對象乌询。

  4. 局限性:父類類型的變量不能直接調(diào)用子類特有的方法榜贴,必須強制轉(zhuǎn)換為子類類型變量后,才能使用妹田。


內(nèi)存管理RAC:

ARC 相對于 GC 的優(yōu)點:
ARC 工作在編譯期大年,在運行時沒有額外開銷彭谁。
ARC 的內(nèi)存回收是平穩(wěn)進行的,對象不被使用時會立即被回收。而 GC 的內(nèi)存回收是一陣一陣的凡恍,回收時需要暫停程序,會有一定的卡頓点额。

ARC 相對于 GC 的缺點:
GC 真的是太簡單了咪啡,基本上完全不用處理內(nèi)存管理問題,而 ARC 還是需要處理類似循環(huán)引用這種內(nèi)存管理問題房铭。

property的關(guān)鍵字分三類:

1.原子性(也就線程安全)

有atomic和nonatomic, acomic就是線程安全驻龟,但是一般使用nonacomic,因為acomic的線程安全開銷太大,影響性能缸匪,即使需要保證線程安全翁狐,我們也可以通過自已的代碼控制,而不用acomic凌蔬。

2.引用計數(shù):

assign:

assign用于非指針變量露懒,基本修飾數(shù)據(jù)類型,統(tǒng)一由系統(tǒng)的棧區(qū)進行內(nèi)存管理砂心。(int懈词、double、float等)

weak:

對對象的弱引用辩诞,不增加引用計數(shù)坎弯,也不持有對象,當對象消失后指針自動變?yōu)閚il。

copy:分為深拷貝抠忘、淺拷貝撩炊,可變復制、不可變復制

淺拷貝:對內(nèi)存地址的復制崎脉,讓目標對象指針和原對象指向同一片內(nèi)存空間會增加引用計數(shù)

深拷貝:對對象內(nèi)容的復制拧咳,開辟新的內(nèi)存空間

單層深復制,也就是我們經(jīng)常說的深復制囚灼,我這里說的單層深復制是對于集合類所說的(即NSArray骆膝、NSDictionary、NSSet)啦撮,單層深復制指的是只復制了該集合類的最外層谭网,里邊的元素沒有復制,(即這兩個集合類的地址不一樣赃春,但是兩個集合里所存儲的元素的地址是一樣的)

完全復制愉择,指的是完全復制整個集合類,也就是說兩個集合地址不一樣织中,里邊所存儲的元素地址也不一樣

引用:深拷貝和淺拷貝锥涕,可變復制,不可變復制(這里解釋更詳細)http://www.reibang.com/p/e3da07684bf1

  • 非集合類(NSString狭吼,NSNumber)
[noMutableObject copy]        //淺復制  (復制不可變對象)
[noMutableObject mutableCopy] //深復制  (復制不可變對象)
[mutableObject copy]        //深復制  (復制可變對象)
[mutableObject mutableCopy] //深復制  (復制可變對象)
  • 集合類(NSArray层坠,NSDictionary, NSSet)
 [noMutableObject copy]        //淺復制    (復制不可變對象)
 [noMutableObject mutableCopy] //單層深復制 (復制不可變對象)
 [mutableObject copy]        //單層深復制 (復制可變對象)
 [mutableObject mutableCopy] //單層深復制 (復制可變對象)
  • 那么如何實現(xiàn)多層復制呢?我們以NSArray舉例說明
 // 完全復制
NSArray *copyArray = [[NSArray alloc] initWithArray:array copyItems:YES]; 
需要特別注意的是

以上我們所說的兩種情況默認都實現(xiàn)了NSCopyingNSMutableCopying協(xié)議刁笙。
對于自定義繼承自NSObject的類

  • copy需要實現(xiàn)NSCopying協(xié)議破花,然后實現(xiàn)以下方法,否則copy會crash
-(id)copyWithZone:(NSZone *)zone {
     CopyObject  *copy = [[[self class] alloc] init];
     copy.name = self.name;
     copy.mobile = self.mobile;
     copy.company = self.company;
     copy.descInfo = self.descInfo;
     return copy;
 } 
  • mutableCopy時疲吸,需要實現(xiàn)NSMutableCopying協(xié)議座每,否則mutableCopy會crash
 -(id)mutableCopyWithZone:(NSZone *)zone {
     MutableCopyObject  *mutableCopy = [[[self class] alloc] init];
     mutableCopy.name = self.name;
     mutableCopy.mobile = self.mobile;
     mutableCopy.company = self.company;
     mutableCopy.descInfo = self.descInfo;
     return mutableCopy;
 }
strong:淺拷貝,也就是指針引用

是每對這個屬性引用一次摘悴,retainCount 就會+1峭梳,只能修飾 NSObject 對象,不能修飾基本數(shù)據(jù)類型蹂喻。是 id 和 對象 的默認修飾符葱椭。

unsafe_unretained:和week 非常相似

可以同時修飾基本數(shù)據(jù)類型和 NSObject 對象 ,其實它本身是 week 的前身 , 在 iOS5 之后口四,基本都用 week 代替了 unsafe_unretained 孵运。 但它們之間還是稍微有點區(qū)別的,并不是完全一樣蔓彩,對上層代碼來說掐松,能用 unsafe_unretained 的地方踱侣,都可以用 week 代替粪小〈蠡牵“同時要注意一點,這個修飾符修飾的變量不屬于編譯器的內(nèi)存管理對象”


二探膊、類別Category

重寫一個類的方式用「繼承」還是「分類」杠愧,取決于具體情況:

  • 假如目標類有許多的子類,我們需要拓展這個類又不希望影響到原有的代碼逞壁,繼承后比較好流济。
  • 如果僅僅是拓展方法,分類更好.(不需要涉及到原先的代碼)
優(yōu)點:
  • 分類中方法的優(yōu)先級比原來類中的方法高腌闯,也就是說绳瘟,在分類中重寫了原來類中的方法,那么分類中的方法會覆蓋原來類中的方法姿骏。+(void)load方法是一個特例糖声,它會在當前類執(zhí)行完之后,category中的再執(zhí)行分瘦。)
  • 可以用runtime進行method swizzling(方法的偷梁換柱)來處理異常調(diào)用的方法蘸泻。
缺點:

通過觀察頭文件我們可以發(fā)現(xiàn),Cocoa框架中的許多類都是通過category來實現(xiàn)功能的嘲玫,可能不經(jīng)意間你就覆蓋了這些方法中的其一悦施,有時候就會產(chǎn)生一些無法排查的異常原因。


其他問題

淺拷貝和深拷貝的區(qū)別去团?

淺拷貝:只復制指向?qū)ο蟮闹羔樎盏羔樦赶蛲粋€地址,而不復制引用對象本身土陪。
深拷貝:復制引用對象本身昼汗。內(nèi)存中存在了兩份獨立對象本身,當修改A 時旺坠,B 不變乔遮。(即:B = [A copy]; )



一、內(nèi)存管理

案例:辦公室開關(guān)燈取刃,有人開燈蹋肮,無人關(guān)燈;進人加一璧疗,出人減一坯辩;第一個開燈的人持有此燈,第一個人能廢棄此燈崩侠,其他人只是弱引用漆魔。

內(nèi)存管理原則:

1.自己生成的對象,自己持有
2.非自己生成的對象,自己也能持有
3.不再需要自己持有的對象時改抡,釋放掉
4.非自己持有的對象矢炼,無法釋放(釋放會崩潰)

對象操作與Objective-C方法的對應
對象操作 Objective-C方法
生成并持有對象 alloc、new阿纤、copy句灌、mutableCopy
持有對象 retain (引用計數(shù)加1)
釋放對象 release(引用計數(shù)減1)
廢棄對象 dealloc(引用計數(shù)為0)

相關(guān)釋放函數(shù):autorelease、NSAutoreleasePool欠拾、@autoreleasepool

2胰锌、非自己生成的對象,自己也能持有

 id obj = [NSMutableArray array];
 [obj retain];

* 使用autorelease方法藐窄,可以取得對象的存在资昧,但是自己不持有對象(obj不立刻釋放掉,注冊到autoreleasePool中)

- (id)object {
    id obj = [[NSObject alloc] init];
    [obj autorelease];
    return obj;
}


ARC 環(huán)境下的使用功能規(guī)則

  • 不能使用retain荆忍、release格带、retainCount、autorelease
  • 不能使用NSAllocateObject东揣、NSDeallocateObject
  • 必須遵循內(nèi)存管理命名規(guī)則(駝峰命名法)
  • 不要顯式調(diào)用dealloc
  • 使用 @autorelease 代替 NSAutoreleasePool
  • 不能使用區(qū)域 (NSZone)
  • 對象型變量不能作為C語言結(jié)構(gòu)體(struct/union)的成員
  • 顯式轉(zhuǎn)換 “id” 和 “void *”


會讓對象引用計數(shù)增加的操作:

1.  new践惑、alloc、retain嘶卧、copy尔觉、mutableCopy
2.  添加視圖:用 addview 把一個控件添加到視圖上,這個控件的引用計數(shù)+1芥吟;
3.  添加數(shù)組:把一個對象添加到數(shù)組中侦铜,數(shù)組內(nèi)部會把這個對象的引用計數(shù)+1;
4.  屬性賦值:會讓對象的引用計數(shù)+1钟鸵;
5.  屬性關(guān)聯(lián):xib中的控件钉稍,跟代碼關(guān)聯(lián)后,會讓對象的引用計數(shù)+1棺耍;
6.  push這個操作會讓對象的引用計數(shù)增加贡未。


ARC、MRC混編

  • ARC環(huán)境下 使用MRC代碼蒙袍,使用 -fno-objc-arc轉(zhuǎn)換
  • MRC環(huán)境下 使用ARC代碼俊卤,使用 -fobjc-arc轉(zhuǎn)換

所有權(quán)修飾符

  • _ _strong 修飾符
  • _ _weak 修飾符
  • _ _unsafe_unretained 修飾符(MRC環(huán)境下使用)
  • _ _autoreleasing 修飾符 (ARC環(huán)境下使用)

1、_ _strong修飾符是id類型和對象類型的默認修飾符害幅,一般是隱式的消恍;

id obj = [[NSObject alloc] init];
//同上
id _ _strong obj = [[NSObject alloc] init];

2、 _ _weak 解決 循環(huán)引用的 修飾符以现,防止內(nèi)存泄漏狠怨。在持有某對象的弱引用時约啊,若該對象被廢棄,則弱引用自動失效佣赖,且被賦值nil恰矩,不在持有該對象(持有的對象超出作用域,會被廢棄銷毀)茵汰。

3枢里、_ _unsafe_unretained 和 _ _weak修飾的變量一樣,因為自己生成并持有的對象不能繼續(xù)為自己所有蹂午,所以生成的對象會被立即釋放。

4彬碱、_ _autoreleasing 隱式修飾符:非自己生成的對象豆胸,自己也能持有,會注冊到自動釋放池中巷疼。


屬性聲明的屬性 與 所有權(quán)修飾符的對應關(guān)系

聲明的屬性 所有權(quán)修飾符 說明
assign _ _unsafe_unretained 修飾基本數(shù)據(jù)類型晚胡,如NSInteger和CGFloat,這些數(shù)值主要存在于棧上嚼沿。
copy _ _strong 每次復制會在內(nèi)存中拷貝一份對象估盘,指針指向不同的地址
retain _ _strong 用來持有對象
strong _ _strong 持有對象,引用計數(shù)會增加1骡尽。該對象只要引用計數(shù)不為0則不會被銷毀遣妥。當然強行將其設為nil可以銷毀它。
unsafe_unretained _ _unsafe_unretained 不安全持有
weak _ _weak 不擁有該對象攀细。其修飾的對象引用計數(shù)不會增加箫踩。無需手動設置,該對象會自行在內(nèi)存中銷毀谭贪。


釋放對象時境钟,廢棄對象不被持有的動作:

1、objc_release (釋放)
2俭识、因為引用計數(shù)為0慨削,所以執(zhí)行dealloc(釋放內(nèi)存)
3、_objc_rootDealloc(根解除)
4套媚、object_dispose(廢棄處理)
5缚态、objc_destructInstance(銷毀)
6、objc_clear_deallocating(清除)


對象被廢棄時凑阶,最后調(diào)用objc_clear_deallocating的動作(相關(guān)表 SideTables):

1猿规、從weak表中獲取廢棄對象的記錄(地址為鍵值)。address= h(key)
2宙橱、將包含在記錄中的所有附有_ _weak修飾符變量的地址姨俩,賦值nil蘸拔。
3、從weak表中刪除該記錄环葵。
4调窍、從引用計數(shù)表中刪除廢棄對象的記錄(地址為鍵值)。


/* MRC環(huán)境
 * NSAutoreleasePool
 * autorelease
 */
- (void)test2 {
    
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    id obj = [[NSObject alloc] init];
    [obj autorelease];
    [pool drain];
   
    //同上
    @autoreleasepool {
        id obj = [[NSObject alloc] init];
        [obj autorelease];
    }
    
 //同上 (ARC:ReferenceCountingVC2 )
 @autoreleasepool {
        id __autoreleaseing obj2;
        obj2 =  obj
    }
}



下面了解幾個概念:

內(nèi)存泄漏:應當廢棄的對象在超出其生存周期后繼續(xù)存在张遭。

野指針:指針變量未初始化邓萨,其值是隨機的;指針釋放后未置空菊卷,指向不存在的內(nèi)存缔恳。

懸垂指針: 指向曾經(jīng)存在的對象,但是該對象已經(jīng)不存在了洁闰。

標記指針: Tagged Pointer
是一種特殊的“指針”歉甚,其特殊在于,其實它存儲的并不是地址扑眉,而是真實的數(shù)據(jù)和一些附加的信息纸泄。(后面做專門講解)

isa 指針: NONPOINTER_ISA
對象的isa指針,用來表明對象所屬的類類型和一些附加信息腰素。(nonPointer_isa 后面做專門講解)


標記指針: Tagged Pointer

tagged pointer是一種特殊的“指針”聘裁,其特殊在于,其實它存儲的并不是地址弓千,而是真實的數(shù)據(jù)和一些附加的信息衡便。

image.png

可以看到,利用tagged pointer后计呈,“指針”即存儲了對象本身砰诵,也存儲了和對象相關(guān)的標記。這時的tagged pointer里面存儲的不是地址捌显,而是一個數(shù)據(jù)集合茁彭。同時,其占用的內(nèi)存空間也由16字節(jié)縮減為8字節(jié)扶歪。
(即:Tagged Pointer = 對象本身 + 對象相關(guān)標記)

我們可以在WWDC2013的《Session 404 Advanced in Objective-C》視頻中理肺,看到蘋果對于Tagged Pointer特點的介紹:
? Tagged Pointer專門用來存儲小的對象,例如NSNumber, NSDate, NSString善镰。

? Tagged Pointer指針的值不再是地址了妹萨,而是真正的值。實際上它不再是一個對象了炫欺,它只是一個披著對象皮的普通變量而已乎完。所以,它的內(nèi)存并不存儲在堆中品洛,也不需要malloc和free树姨。

? 在內(nèi)存讀取上有著3倍的效率摩桶,創(chuàng)建時比以前快10倍

例如:NSString 其輸出的class類型為 NSTaggedPointerString。在字符串長度在9個以內(nèi)時帽揪,iOS其實使用了tagged pointer做了優(yōu)化的硝清。
直到字符串長度大于9,字符串才真正成為了__NSCFString類型转晰。
首先芦拿,iOS需要一個標志位來判斷當前指針是真正的指針還是tagged pointer。

在runtime源碼的objc-internal.h中查邢,有關(guān)于標志位的定義如下:

#if __has_feature(objc_fixed_enum)  ||  __cplusplus >= 201103L
enum objc_tag_index_t : uint16_t
#else
typedef uint16_t objc_tag_index_t;
enum
#endif
{
    OBJC_TAG_NSAtom            = 0, 
    OBJC_TAG_1                 = 1, 
    OBJC_TAG_NSString          = 2, // 標志位是2的 tagger pointer表示這是一個NSString對象蔗崎。
    OBJC_TAG_NSNumber          = 3, 
    OBJC_TAG_NSIndexPath       = 4, 
    OBJC_TAG_NSManagedObjectID = 5, 
    OBJC_TAG_NSDate            = 6, 
    OBJC_TAG_RESERVED_7        = 7, 

    OBJC_TAG_First60BitPayload = 0, 
    OBJC_TAG_Last60BitPayload  = 6, 
    OBJC_TAG_First52BitPayload = 8, 
    OBJC_TAG_Last52BitPayload  = 263, 

    OBJC_TAG_RESERVED_264      = 264
};
#if __has_feature(objc_fixed_enum)  &&  !defined(__cplusplus)
typedef enum objc_tag_index_t objc_tag_index_t;
#endif
  • ‘地址’以 0xa開頭,轉(zhuǎn)換為二進制是1010, 首位1表示這是一個tagged pointer侠坎,而010轉(zhuǎn)換為十進制是2蚁趁,表示這是一個NSString類型

  • ‘地址’以0xb開頭实胸, 轉(zhuǎn)換為二進制是1011, 首位1表示這是一個tagged pointer, 而011轉(zhuǎn)換為十進制是3,表示這是一個NSNumber類型番官。
    (即:標志位是2的tagger pointer表示這是一個NSString對象庐完。)
    由于一個tagged pointer所指向的并不是一個真正的OC對象,它其實是沒有isa屬性的徘熔。


isa 指針(NONPOINTER_ISA)

isa:是一個指向?qū)ο笏鶎貱lass類型的指針门躯。(nonPointer_isa)
對象的isa指針,用來表明對象所屬的類類型和一些附加信息酷师。

如果isa指針僅表示類型的話讶凉,對內(nèi)存顯然也是一個極大的浪費。于是山孔,就像tagged pointer一樣懂讯,對于isa指針,蘋果同樣進行了優(yōu)化台颠。isa指針表示的內(nèi)容變得更為豐富褐望,除了表明對象屬于哪個類之外,還附加了 「引用計數(shù)」extra_rc串前,是否有被weak引用標志位weakly_referenced瘫里,是否有附加對象標志位has_assoc等信息。(rc:reference counter 引用計數(shù))

//------- NSObject(實質(zhì)) ------- 
@interface NSObject <NSObject> {
    Class isa  OBJC_ISA_AVAILABILITY;
}

//------- objc_class(繼承)------- 
struct objc_class : objc_object {
    // Class ISA;
    Class superclass;
    cache_t cache;             // formerly cache pointer and vtable         以前的緩存指針和虛函數(shù)表
    class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags   class_rw_t *加上自定義rr/alloc標志
    //荡碾。谨读。。
}

//------- isa指針(指向)------- 
struct objc_object {
private:
    isa_t isa;

public:
    Class ISA();        // ISA() assumes this is NOT a tagged pointer object    假設這不是一個標記的指針對象
    Class getIsa(); // getIsa() allows this to be a tagged pointer object   允許這是一個標記的指針對象
    //坛吁。劳殖。铐尚。
}

//------- 聯(lián)合體(定義)------- 
union isa_t 
{
    isa_t() { }                             //構(gòu)造函數(shù)1
    isa_t(uintptr_t value) : bits(value) { }    //構(gòu)造函數(shù)2
    Class cls;          //成員1(占據(jù)64位內(nèi)存空間)
    uintptr_t bits;     //成員2(占據(jù)64位內(nèi)存空間)

#if SUPPORT_PACKED_ISA
# if __arm64__
#   define ISA_MASK        0x0000000ffffffff8ULL
#   define ISA_MAGIC_MASK  0x000003f000000001ULL
#   define ISA_MAGIC_VALUE 0x000001a000000001ULL
    struct {                //成員3(占據(jù)64位內(nèi)存空間:從低位到高位依次是nonpointer到extra_rc。成員后面的:表明了該成員占用幾個bit闷尿。)
        uintptr_t nonpointer        : 1;  //(低位)注意:標志位塑径,表明isa_t *是否是一個真正的指針!L罹摺统舀!
        uintptr_t has_assoc         : 1;  // 關(guān)聯(lián)對象
        uintptr_t has_cxx_dtor      : 1;
        uintptr_t shiftcls          : 33; // MACH_VM_MAX_ADDRESS 0x1000000000
        uintptr_t magic             : 6;
        uintptr_t weakly_referenced : 1;  //弱引用
        uintptr_t deallocating      : 1;
        uintptr_t has_sidetable_rc  : 1;  //引用計數(shù) 相關(guān)成員1
        uintptr_t extra_rc          : 19; //引用計數(shù) 相關(guān)成員2 (用19位來 記錄對象的引用次數(shù))
#       define RC_ONE   (1ULL<<45)
#       define RC_HALF  (1ULL<<18)
    };
}



引用于書籍《Objective-C高級編程》
GNUstep 是Cocoa 框架的互換框架。
CF:Core Foundation
CFRutime.c
蘋果的實現(xiàn)大概是采用散列表(引用計數(shù)表)來管理引用計數(shù)劳景。

在runtime中誉简,有四個數(shù)據(jù)結(jié)構(gòu)非常重要,分別是SideTables盟广、SideTable闷串、weak_table_tweak_entry_t。它們和對象的引用計數(shù)筋量,以及weak引用相關(guān)烹吵。
(相關(guān)記錄,我的電腦文件:101-Runtime基礎(chǔ))

引用計數(shù)表的關(guān)系

其實在絕大多數(shù)情況下桨武,僅用優(yōu)化的isa_t 來記錄對象的引用計數(shù)就足夠了肋拔。只有在19位的extra_rc盛放不了那么大的引用計數(shù)時,才會借助SideTable出馬呀酸。
SideTable:是一個 全局的引用計數(shù)表凉蜂,它記錄了所有對象的引用計數(shù)。

先說一下這四個數(shù)據(jù)結(jié)構(gòu)的關(guān)系性誉。 在runtime內(nèi)存空間中窿吩,SideTables 是一個長度為8個元素 的hash數(shù)組,里面存儲了SideTable错览。SideTables的hash鍵值就是一個對象obj的address纫雁。即:table1 = h(address1)
因此可以說,一個obj蝗砾,對應了一個SideTable先较。但是一個SideTable,會對應多個obj悼粮。因為SideTable的數(shù)量只有64個闲勺,所以會有很多obj共用同一個SideTable

SideTables

SideTable地址 關(guān)鍵字
table1 = h ( address1 ) address1
table2 = h ( address2 ) address1
table3 = h ( address3 ) address1
... ...

SideTable

obj對象地址 關(guān)鍵字
address1 = h ( key1 ) 扣猫、RefcountMap1菜循、weak_table1 key1
address2 = h ( key2 ) 、RefcountMap2申尤、weak_table2 key2
address3 = h ( key3 )癌幕、RefcountMap3衙耕、weak_table3 key3
... ...

而在一個SideTable中,又有3個成員勺远,分別是:

  • spinlock_t slock: 自旋鎖橙喘,用于上鎖/解鎖 SideTable。
  • RefcountMap refcnts :以DisguisedPtr<objc_object>為key的hash表胶逢,用來存儲OC對象的引用計數(shù)(僅在未開啟isa優(yōu)化 或 在isa優(yōu)化情況下isa_t的引用計數(shù)溢出時才會用到)厅瞎。
  • weak_table_t weak_table : 存儲對象弱引用指針的hash表。是OC weak功能實現(xiàn)的核心數(shù)據(jù)結(jié)構(gòu)初坠。

struct weak_table_t {
weak_entry_t *weak_entries; // 保存了所有指向指定對象的 weak 指針
size_t num_entries; // 存儲空間
uintptr_t mask; // 參與判斷引用計數(shù)輔助量
uintptr_t max_hash_displacement; // hash key 最大偏移值
};

其中和簸,refcents是一個hash map,其key是obj的地址碟刺,而value锁保,則是obj對象的引用計數(shù)。 即:referenceCount = h ( address )

weak_table則存儲了弱引用obj的指針的地址半沽,其本質(zhì)是一個以obj地址為key爽柒,弱引用obj的指針的地址作為value的hash表。hash表的節(jié)點類型是weak_entry_t者填。 即:objPointer = h ( address )

SideTables關(guān)系圖.png

二霉赡、Block

iOS全解1-2:Block 詳解

三、GCD與多線程

iOS全解1-3:鎖幔托、GCD與多線程
iOS全解1-4:NSURLSession




參考文章,如有問題請聯(lián)系本人QQ1178690076
Object-C高級編程讀書筆記(1)——Block的基本概念
Object-C高級編程讀書筆記(2)——Block的實質(zhì)
Object-C高級編程讀書筆記(3)——Block的變量截取
Object-C高級編程讀書筆記(4)——__block說明符
Object-C高級編程讀書筆記(5)——Block的對象類型截取


Objective-C runtime機制(1)——基本數(shù)據(jù)結(jié)構(gòu):objc_object & objc_class
Objective-C runtime機制(2)——消息機制
Objective-C runtime機制(3)——method swizzling
Objective-C runtime機制(4)——深入理解Category
Objective-C runtime機制(5)——iOS 內(nèi)存管理
Objective-C runtime機制(6)——weak引用的底層實現(xiàn)原理

Objective-C runtime機制(7)——SideTables, SideTable, weak_table, weak_entry_t
Objective-C runtime機制(8)——OC對象從創(chuàng)建到銷毀
Objective-C runtime機制(9)——main函數(shù)前發(fā)生了什么
Objective-C runtime機制(10)——KVO的實現(xiàn)機制
Objective-C runtime機制(11)——結(jié)業(yè)考試

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蜂挪,一起剝皮案震驚了整個濱河市重挑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌棠涮,老刑警劉巖谬哀,帶你破解...
    沈念sama閱讀 221,576評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異严肪,居然都是意外死亡史煎,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評論 3 399
  • 文/潘曉璐 我一進店門驳糯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來篇梭,“玉大人,你說我怎么就攤上這事酝枢√裢担” “怎么了?”我有些...
    開封第一講書人閱讀 168,017評論 0 360
  • 文/不壞的土叔 我叫張陵帘睦,是天一觀的道長袍患。 經(jīng)常有香客問我坦康,道長,這世上最難降的妖魔是什么诡延? 我笑而不...
    開封第一講書人閱讀 59,626評論 1 296
  • 正文 為了忘掉前任滞欠,我火速辦了婚禮,結(jié)果婚禮上肆良,老公的妹妹穿的比我還像新娘筛璧。我一直安慰自己,他們只是感情好妖滔,可當我...
    茶點故事閱讀 68,625評論 6 397
  • 文/花漫 我一把揭開白布隧哮。 她就那樣靜靜地躺著,像睡著了一般座舍。 火紅的嫁衣襯著肌膚如雪沮翔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,255評論 1 308
  • 那天曲秉,我揣著相機與錄音采蚀,去河邊找鬼。 笑死承二,一個胖子當著我的面吹牛榆鼠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播亥鸠,決...
    沈念sama閱讀 40,825評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼妆够,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了负蚊?” 一聲冷哼從身側(cè)響起神妹,我...
    開封第一講書人閱讀 39,729評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎家妆,沒想到半個月后鸵荠,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,271評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡伤极,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,363評論 3 340
  • 正文 我和宋清朗相戀三年蛹找,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片哨坪。...
    茶點故事閱讀 40,498評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡庸疾,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出齿税,到底是詐尸還是另有隱情彼硫,我是刑警寧澤,帶...
    沈念sama閱讀 36,183評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站拧篮,受9級特大地震影響词渤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜串绩,卻給世界環(huán)境...
    茶點故事閱讀 41,867評論 3 333
  • 文/蒙蒙 一缺虐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧礁凡,春花似錦高氮、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至窟蓝,卻和暖如春罪裹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背运挫。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評論 1 272
  • 我被黑心中介騙來泰國打工状共, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人谁帕。 一個月前我還...
    沈念sama閱讀 48,906評論 3 376
  • 正文 我出身青樓峡继,卻偏偏與公主長得像,于是被迫代替她去往敵國和親匈挖。 傳聞我的和親對象是個殘疾皇子碾牌,可洞房花燭夜當晚...
    茶點故事閱讀 45,507評論 2 359

推薦閱讀更多精彩內(nèi)容