https://justsee.iteye.com/blog/2163905
總結:
1.實例對象 (類對象的實例對象):實例對象是運行的時候生成的,都是在運行時由Objective-C的運行時庫生成的。
2.類對象 (元類對象的一個實例)是由編譯器創(chuàng)建的。
3.元類對象是根元類對象的一個實例。是由編譯器創(chuàng)建的。
1.people為例子, People *people = [[People alloc] init];
編譯器會生成 2個對象,people 是類對象object_getClass(people)的實例,object_getClass(people)是元類object_getClass(object_getClass(classPeople))的實例。
2.1.類對象里面有方法 get set 方法,方法--1--classMthod1 屬性:year name age
2.元類對象里面有方法 classMthod2 屬性:year name age
3.根元類里面有方法 -isEqual: allocWithZone: release respondsToSelector nsobject.h所具有的。
屬性:屬性名稱--3--accessInstanceVariablesDirectly



1.runtime 運行時系統(tǒng),runtime是由c和匯編寫的。
編譯器會將OC代碼轉換成運行時候的代碼,在運行時確定數據結構和函數。
編譯器和JAVA的比較。NSProxy NSObject?
http://m.itdecent.cn/p/d4b55dae9a0d
OC是動態(tài)語言,不像C語言一樣,編譯階段就要決定調用哪個函數,如果函數未實現就會編譯報錯,
OC 編譯階段并不能決定真正的調用哪個函數,只要函數聲明過即使沒有實現不會報錯。
我們常說OC是一門動態(tài)語言,就是因為它總是把一些決定性的工作從編譯階段推遲到運行時階段。OC代碼的運行不僅需要編譯器,還需要運行時系統(tǒng)(Runtime Sytem)來執(zhí)行編譯后的代碼。
2.類對象,實例對象,和元類對象。
oc動態(tài)性:
1.動態(tài)類型:id類型。
2.動態(tài)綁定:一般在編譯的時候就已經將要調用的函數的函數簽名都告訴編譯器了。靜 態(tài)的,不能改變。而在OC中,其實是沒有函數的概念的,我們叫“消息機制”,所謂的 函數調用就是給對象發(fā)送一條消息。這時,動態(tài)綁定的特性就來了。OC可以先跳過編 譯,到運行的時候才動態(tài)地添加函數調用,在運行時才決定要調用什么方法,需要傳 什么參數進去,這就是
3動態(tài)加載:動態(tài)地加載資源,在運行時加載新類。
1.Rutime消息發(fā)送.
1.編譯語言與OBJC 運行動態(tài)語言的區(qū)別是什么?
2.消息傳遞機制與函數調用區(qū)別?
3.消息轉發(fā)?
4.方法緩存,
1.數據結構,類對象元類對象,消息傳遞,方法緩存,
消息轉發(fā) method-swizzling 方法混淆,運行時候去替換方法。
動態(tài)添加方法,動態(tài)方法解析
typedef struct objc_object {
Class isa;
} *id;
id—objc_object—isa
—弱引用相關
—關聯(lián)對象相關
—內存管理相關 retain release pool
**Class = objc_class **
struct objc_class {
Class isa;
if !OBJC2
Class super_class OBJC2_UNAVAILABLE;
const char *name OBJC2_UNAVAILABLE;
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE;
struct objc_method_list **methodLists OBJC2_UNAVAILABLE;
struct objc_cache *cache OBJC2_UNAVAILABLE;
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;
endif
}
http://m.itdecent.cn/p/45db86af7b60
指針型:isa的值代表class 的地址。
非指針型isa:isa的值部分代表class的地址。
實例isa——> Class 類對象。——> Class 元類對象。
1.cathe_t 用于快速查找方法執(zhí)行函數。
2.可增量擴展的哈希表結構。擴大內存空間,為了提高查找效率。
3.局部性原理。調用頻率最高的放到緩存表。
數組
**bucket_t bucket_t. bucket_t bucket_t **
Key IMP
class_data_bits_t 對class_rw_t的封裝。
class_rw_t代表了類相關的讀寫信息,對class_ro_t 的封裝。
class_ro_t代表了類相關的只讀信息。
//二維數組———》分類
typedef struct class_rw_t {
uint32_t flags;
uint32_t version;
const class_ro_t *ro;
method_list_t **methods;
struct chained_property_list *properties;
const protocol_list_t ** protocols;
struct class_t *firstSubclass;
struct class_t *nextSiblingClass;
} class_rw_t;
//一維數組—原始定義的添加的。
typedef struct class_ro_t {
uint32_t flags;
uint32_t instanceStart;
uint32_t instanceSize;
ifdef LP64
uint32_t reserved;
endif
const uint8_t * ivarLayout;
const char * name;
const method_list_t * baseMethods;
const protocol_list_t * baseProtocols;
const ivar_list_t * ivars;
const uint8_t * weakIvarLayout;
const property_list_t *baseProperties;
} class_ro_t;
method_t
根類的父類是nil.
1.實例對象,類對象,元類對象,
1.子類元類,父類對象,根類對象都指向根類對象。
**2.objct_getclass **
3.子類元類superclass是父類元類對象superclass是根類元類對象superclass找同名的實例類對象。
2.
super是一個編譯器標識符,在運行時中與self相同,指向同一個消息接受者,只是self會優(yōu)先在當前類的methodLists中查找方法,而super則是優(yōu)先從父類中查找
objc_msgSend((id)self, sel_registerName("class"));
objc_msgSendSuper((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("JQApple"))}, sel_registerName("class"));
struct objc_super {
/// Specifies an instance of a class.
__unsafe_unretained id receiver;
/// Specifies the particular superclass of the instance to message.
__unsafe_unretained Class super_class;
/* super_class is the first class to search */
};
我們把self以及JQApple的父類通過結構體的構造方法構造了一個__rw_objc_super結構體,也就是objc_super
因此objc_super結構體中的receiver既是self。所以[self class]和[super class]指向的是同一個消息接受者,
3.消息傳遞:
self class objc_msgsend (id self,SEL op)編譯器層
objc_msgSend((id)self, sel_registerName("class"));
objc_msgSendSuper((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("JQApple"))}, sel_registerName("class"));
class_getSuperclass
__rw_objc_super
對象方法
首先查緩存列表—isa—當前類對象方法列表—super—父類緩存/方法列表——nsobject根—nil
類方法
首先查緩存列表—isa—isa—元類對象類方法列表—super—父類緩存類方法列表——根元類—-同名實例對xiang
4.緩存查找 ——》哈希算法。———》擴展
緩存查找:SEL
hash算出的值
key & mask = f(key)
目標值是bucket_t中的IMP.哈希查找,根據f(key) 查找出bucket_t.提取對應的imp.
5.當前類中的查找—————》二分查找———》擴展
已經排序好的列表,采用二分查找算法查找方法對應執(zhí)行函數。
沒有排序的列表,采用一般遍歷查找方法對應執(zhí)行函數。
6.父類逐級查找
先檢查父類緩存—>superclass 方法列表—>然后父類緩存—>方法列表。
7.消息轉發(fā)流程:
+resolveInstanceMethod: 或 +resolveClassMethod:
證書,簽名等等。。。
跨平臺。
1.動態(tài)方法解析。
resolveinstancemthod.

2.快速消息轉發(fā)。
forwardTargetforselctor

3.標準消息轉發(fā)。
methodSignatureForSelector:
forwardInvocation:
v void類型, @代表第一個參數類型id self :代表第二個參數是SEL類型的。


4.runtime的應用:
1.runtime交換方法:

2.動態(tài)添加方法:

[圖片上傳中...(Xnip2019-04-17_15-49-11.jpg-3613fc-1555498321835-0)]
3.分類添加屬性:

4.KVO實現———》擴展
KVO實現
KVO的實現依賴于 Objective-C 強大的 Runtime,當觀察某對象 A 時,KVO 機制動態(tài)創(chuàng)建一個對象A當前類的子類,并為這個新的子類重寫了被觀察屬性 keyPath 的 setter 方法。setter 方法隨后負責通知觀察對象屬性的改變狀況。
5.實現NSCoding的自動歸檔和自動解檔

6.load方法:
oc中 +load方法的深層理解
https://blog.csdn.net/wei371522/article/details/81211346
- load 作為 Objective-C 中的一個方法,與其它方法有很大的不同。它只是一個在整個文件被加載到運行時,在 main 函數調用之前被 ObjC 運行時調用的鉤子方法。其中關鍵字有這么幾個:
文件剛加載
main 函數之前
鉤子方法
