ios淺談runtime

老樣子..先看文檔 知道 runtime 到底是個(gè)什么東西呢.....

The Objective-C language defers as many decisions as it can from compile time and link time to runtime. Whenever possible, it does things dynamically. This means that the language requires not just a compiler, but also a runtime system to execute the compiled code. The runtime system acts as a kind of operating system for the Objective-C language; it’s what makes the language work.

runtime 使objc變成了真正的動(dòng)態(tài)語言,是objc 的操作系統(tǒng).objc 延遲了許多決定,直到運(yùn)行時(shí)才做出.runtime 給了 objc 真正的動(dòng)態(tài)性

runtime 運(yùn)行時(shí)有兩個(gè)版本,一般手機(jī)和64位機(jī)器的用的是現(xiàn)代版本,一般32位的機(jī)器用的是古老版本..我們接下來都是以現(xiàn)代版本進(jìn)行解釋的

和 objc-runtime 交互有三種方式

  1. 通過 objc 源代碼 我們?cè)趯?objc 源代碼的時(shí)候,在編譯期間有的就已經(jīng)被翻譯優(yōu)化了.背后變成了調(diào)用運(yùn)行時(shí)的代碼
  2. 就是通過 nsobject 中的一些方法 nsobject 不規(guī)定類的具體行為.只定義了它們的基本必須結(jié)構(gòu)
  3. 最后的,自然就是通過runtime函數(shù)庫直接調(diào)用

how the message expressions are converted into objc_msgSend function calls, and how you can refer to methods by name. It then explains how you can take advantage of objc_msgSend, and how—if you need to—you can circumvent dynamic binding.

如果你對(duì)objc消息機(jī)制掌握的很好,完全可以繞過動(dòng)態(tài)綁定實(shí)現(xiàn)黑魔法
消息的最終接收者都是在運(yùn)行時(shí)才確定的

[receiver message]
編譯器轉(zhuǎn)換為:
objc_msgSend(receiver, selector) //兩個(gè)必須參數(shù)
objc_msgSend(receiver, selector, arg1, arg2, ...)//之后可選參數(shù)

The messaging function does everything necessary for dynamic binding:

It first finds the procedure (method implementation) that the selector refers to. Since the same method can be implemented differently by separate classes, the precise procedure that it finds depends on the class of the receiver.
It then calls the procedure, passing it the receiving object (a pointer to its data), along with any arguments that were specified for the method.
Finally, it passes on the return value of the procedure as its own return value.

作用:根據(jù)message 和 receiver的類的找到唯一的方法

我們先來看看類是什么 objc-class

 struct objc_class {
 Class isa  OBJC_ISA_AVAILABILITY;                       //指向元類

#if !__OBJC2__
Class super_class             //指向父類                           OBJC2_UNAVAILABLE;
const char *name              //類名                          OBJC2_UNAVAILABLE;
long version                  //版本信息                            OBJC2_UNAVAILABLE;
long info                     //類信息   供運(yùn)行時(shí)使用的標(biāo)識(shí)符                           OBJC2_UNAVAILABLE;
long instance_size            //實(shí)例大小                           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..//協(xié)議鏈表                     OBJC2_UNAVAILABLE;
#endif

} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */

typedef struct objc_class *Class;

這是需要了解的東西 一個(gè)實(shí)例中都有一個(gè) isa 指針,指向一個(gè) Class(objc_class*)的結(jié)構(gòu)體的指針,也就是實(shí)例指向自己的類,類中也有一個(gè) Class(isa)指向元類.一切皆對(duì)象中,類也是對(duì)象

可以看到很清楚顯示了實(shí)例和類之間的關(guān)系


When a message is sent to an object, the messaging function follows the object’s isa pointer to the class structure where it looks up the method selector in the dispatch table. If it can’t find the selector there, objc_msgSend follows the pointer to the superclass and tries to find the selector in its dispatch table. Successive failures cause objc_msgSend to climb the class hierarchy until it reaches the NSObject class. Once it locates the selector, the function calls the method entered in the table and passes it the receiving object’s data structure.

當(dāng)一個(gè)消息被發(fā)送到一個(gè)對(duì)象時(shí),函數(shù)調(diào)度機(jī)制根據(jù)這個(gè)對(duì)象的 isa 指針找到類的繼承結(jié)構(gòu)在類中的 dispatch_table 中找到這個(gè)方法,循環(huán)向上,找到之后,才開始進(jìn)行執(zhí)行 行話就是動(dòng)態(tài)綁定.....
為了加速動(dòng)態(tài)綁定的速度,每個(gè)類都有一個(gè)調(diào)度緩存,一些多次被使用的方法指針都在這里,在進(jìn)行調(diào)用表查詢之前,所有的方法都會(huì)先去查詢這個(gè) cache 中的方法.

isa:需要注意的是在Objective-C中梨树,所有的類自身也是一個(gè)對(duì)象诈悍,這個(gè)對(duì)象的Class里面也有一個(gè)isa指針黎侈,它指向metaClass(元類)淤年,

super_class:指向該類的父類彪薛,如果該類已經(jīng)是最頂層的根類(如NSObject或NSProxy),則super_class為NULL。

cache:用于緩存最近使用的方法。一個(gè)接收者對(duì)象接收到一個(gè)消息時(shí)佩厚,它會(huì)根據(jù)isa指針去查找能夠響應(yīng)這個(gè)消息的對(duì)象。在實(shí)際使用中说订,這個(gè)對(duì)象只有一部分方法是常用的抄瓦,很多方法其實(shí)很少用或者根本用不上。這種情況下陶冷,如果每次消息來時(shí)钙姊,我們都是methodLists中遍歷一遍,性能勢(shì)必很差埂伦。這時(shí)煞额,cache就派上用場(chǎng)了。在我們每次調(diào)用過一個(gè)方法后沾谜,這個(gè)方法就會(huì)被緩存到cache列表中膊毁,下次調(diào)用的時(shí)候runtime就會(huì)優(yōu)先去cache中查找,如果cache沒有类早,才去methodLists中查找方法媚媒。這樣嗜逻,對(duì)于那些經(jīng)常用到的方法的調(diào)用涩僻,但提高了調(diào)用的效率。就是緩存方法

現(xiàn)在看看對(duì)象的定義 (所有的都是經(jīng)過c包裝后的)

/// Represents an instance of a class.
struct objc_object {
Class isa  OBJC_ISA_AVAILABILITY; //實(shí)例對(duì)象擁有指向類的指針
};

typedef struct objc_object *id;    

當(dāng)創(chuàng)建一個(gè)特定類的實(shí)例對(duì)象時(shí),分配的內(nèi)存包含一個(gè)objc_object數(shù)據(jù)結(jié)構(gòu),NSObject類的alloc和allocWithZone:方法底層調(diào)用函數(shù)class_createInstance來創(chuàng)建objc_object數(shù)據(jù)結(jié)構(gòu).

常見的id逆日,它是一個(gè)objc_object結(jié)構(gòu)類型的指針嵌巷。 代表任何對(duì)象

meta-class是一個(gè)類對(duì)象的類。
當(dāng)我們向一個(gè)對(duì)象發(fā)送消息時(shí)室抽,runtime會(huì)在這個(gè)對(duì)象所屬的這個(gè)類的方法列表中查找方法搪哪;而向一個(gè)類發(fā)送消息時(shí),會(huì)在這個(gè)類的meta-class的方法列表中查找坪圾。

meta-class存儲(chǔ)著一個(gè)類的所有類方法晓折。每個(gè)類都會(huì)有一個(gè)單獨(dú)的meta-class.所有meta-class類的isa 指向的都是 NSObject的meta-class類..也就是當(dāng)我們調(diào)用類方法的時(shí)候,實(shí)際是去元類中查找.....


類與對(duì)象操作函數(shù)

runtime提供了大量的函數(shù)來操作類與對(duì)象。類的操作方法大部分是以class為前綴的兽泄,而對(duì)象的操作方法大部分是以objc或object_為前綴漓概。

When objc_msgSend finds the procedure that implements a method, it calls the procedure and passes it all the arguments in the message. It also passes the procedure two hidden arguments:

The receiving object
The selector for the method
These arguments give every method implementation explicit information about the two halves of the message expression that invoked it. They’re said to be “hidden” because they aren’t declared in the source code that defines the method. They’re inserted into the implementation when the code is compiled.

每底層objc_msgsend的方法在運(yùn)行時(shí)都會(huì)有兩個(gè)隱含的參數(shù) 在編譯時(shí)被自動(dòng)添加 一個(gè)是 self.指向receiver 一個(gè)是_cmd..代表的是方法本身
下面官方代碼測(cè)試這兩個(gè)參數(shù)

   - strange
 {
    id  target = getTheReceiver();
    SEL method = getTheMethod();
    
    if ( target == self || method == _cmd )
        return nil;
    return [target performSelector:method];
} 

self 很有用啊,我們不是經(jīng)常通過 self 獲得消息和成員變量嘛

每次執(zhí)行方法的時(shí)候,都需要在調(diào)度表中查詢找到函數(shù)的入口地址,這對(duì)于一般方法沒問題.但是對(duì)于需要超高效率和執(zhí)行次數(shù)多的方法,我們可以直接跳過動(dòng)態(tài)綁定

sing methodForSelector: to circumvent dynamic binding saves most of the time required by messaging. However, the savings will be significant only where a particular message is repeated many times, as in the for loop shown above.

我們一般用 methodForSelector 來跳過動(dòng)態(tài)綁定這]法是得到 selector 的實(shí)際函數(shù)

| SEL1 | SEL2 | SEL3 |

| IMP1 | IMP2 | IMP3 |

sel 只是一個(gè)方法的標(biāo)志符,真正的執(zhí)行代碼地址是 imp 指向的地方 methodforselector可以的某個(gè)方法標(biāo)識(shí)符的地址,我們也可以在程序中之直接使用

IMP imp =  [ NSObject methodForSelector:@selector(class)];
imp();


typedef id (*IMP)(id, SEL,... );

IMP is a C type referring to the implementation of a method, also known as an implementation pointer. It's a pointer to a function returning id, and with self and a method selector (available inside method definitions as the variable _cmd) as the first arguments

可以看到 id 是一種數(shù)據(jù)類型,imp 是一個(gè)指向返回?cái)?shù)據(jù)類型是 id 的函數(shù)的指針,這個(gè)函數(shù)的第一個(gè)參數(shù)和第二個(gè)參數(shù)是self 和這個(gè)函數(shù)名_cmd;

objc 將許多需要編譯和鏈接時(shí)確定的延遲到運(yùn)行時(shí)確定,這樣就發(fā)生了許多有趣的東西.比如.我們可以動(dòng)態(tài)的給類添加屬性使用 @dynamic propertyName;
動(dòng)態(tài)的告訴編譯器消息使用的屬性

我們也可以動(dòng)態(tài)的給類添加方法.(所有的這些和 java 中因?yàn)橛刑摂M機(jī)而有的反射有異曲同工之妙)

 void dynamicMethodIMP(id self, SEL _cmd) {
// implementation ....
}
@implementation MyClass
+ (BOOL)resolveInstanceMethod:(SEL)aSEL
{
    if (aSEL == @selector(resolveThisMethodDynamically)) {
          class_addMethod([self class], aSEL, (IMP) dynamicMethodIMP, "v@:");
          return YES;
    }
    return [super resolveInstanceMethod:aSEL];
}

class_addMethod 接收的參數(shù):要添加的類 ,方法標(biāo)識(shí)符 sel;方法執(zhí)行入口地址;描述符

我們一定要有一個(gè)意識(shí)(runtime 是 一個(gè)函數(shù)庫 幫助我們更好的處理 objc 和 java 虛擬機(jī)做的事情是很類似的 這是動(dòng)態(tài)語言的一個(gè)大特性)

消息轉(zhuǎn)發(fā)
當(dāng)一個(gè)對(duì)象能接收一個(gè)消息時(shí),就會(huì)走正常的方法調(diào)用流程病梢。但如果一個(gè)對(duì)象無法接收指定消息時(shí)胃珍,又會(huì)發(fā)生什么事呢?默認(rèn)情況下蜓陌,如果是以 [object message]的方式調(diào)用方法觅彰,如果object無法響應(yīng)message消息時(shí),編譯器會(huì)報(bào)錯(cuò)钮热。但如果是以perform…的形式來調(diào)用填抬,則需要等到運(yùn) 行時(shí)才能確定object是否能接收message消息。如果不能隧期,則程序崩潰痴奏。
所以我們不能確定一個(gè)對(duì)象是否可以接受一個(gè)消息的時(shí)候,會(huì)先進(jìn)行判斷

if ([self respondsToSelector:@selector(method)]) {
[self performSelector:@selector(method)];
}

當(dāng)一個(gè)對(duì)象無法接收某一消息時(shí),就會(huì)啟動(dòng)所謂”消息轉(zhuǎn)發(fā)(message forwarding)“機(jī)制厌秒,通過這一機(jī)制读拆,我們可以告訴對(duì)象如何處理未知的消息。默認(rèn)情況下鸵闪,對(duì)象接收到未知的消息檐晕,會(huì)導(dǎo)致程序崩潰,報(bào)錯(cuò)

untime的強(qiáng)大之處在于它能在運(yùn)行時(shí)創(chuàng)建類和對(duì)象。

動(dòng)態(tài)創(chuàng)建類

動(dòng)態(tài)創(chuàng)建類涉及到以下幾個(gè)函數(shù):

// 創(chuàng)建一個(gè)新類和元類

Class objc_allocateClassPair ( Class superclass, const char *name, size_t extraBytes );

// 銷毀一個(gè)類及其相關(guān)聯(lián)的類

void objc_disposeClassPair ( Class cls );

// 在應(yīng)用中注冊(cè)由objc_allocateClassPair創(chuàng)建的類

void objc_registerClassPair ( Class cls );

和 java 中的反射有異曲同工之妙

息轉(zhuǎn)發(fā)機(jī)制基本上分為三個(gè)步驟:

  1. 動(dòng)態(tài)方法解析

  2. 備用接收者

  3. 完整轉(zhuǎn)發(fā)

下面我們?cè)敿?xì)討論一下這三個(gè)步驟蚌讼。

動(dòng)態(tài)方法解析

對(duì)象在接收到未知的消息時(shí)辟灰,首先會(huì)調(diào)用所屬類的類方法+resolveInstanceMethod:(實(shí)例方法)或 者+resolveClassMethod:(類方法)。在這個(gè)方法中篡石,我們有機(jī)會(huì)為該未知消息新增一個(gè)”處理方法”“芥喇。不過使用該方法的前提是我們已經(jīng) 實(shí)現(xiàn)了該”處理方法”,只需要在運(yùn)行時(shí)通過class_addMethod函數(shù)動(dòng)態(tài)添加到類里面就可以了凰萨。如下代碼所示:

void functionForMethod1(id self, SEL _cmd) {
   NSLog(@"%@, %p", self, _cmd);
}

+ (BOOL)resolveInstanceMethod:(SEL)sel {

NSString *selectorString = NSStringFromSelector(sel);

if ([selectorString isEqualToString:@"method1"]) {
    class_addMethod(self.class, @selector(method1), (IMP)functionForMethod1, "@:");
}

return [super resolveInstanceMethod:sel];
}

不過這種方案更多的是為了實(shí)現(xiàn)@dynamic屬性继控。

備用接收者

如果在上一步無法處理消息械馆,則Runtime會(huì)繼續(xù)調(diào)以下方法:

  • (id)forwardingTargetForSelector:(SEL)aSelector
    如果一個(gè)對(duì)象實(shí)現(xiàn)了這個(gè)方法,并返回一個(gè)非nil的結(jié)果武通,則這個(gè)對(duì)象會(huì)作為消息的新接收者霹崎,且消息會(huì)被分發(fā)到這個(gè)對(duì)象。當(dāng)然這個(gè)對(duì)象不能是self自身冶忱,否則就是出現(xiàn)無限循環(huán)尾菇。當(dāng)然,如果我們沒有指定相應(yīng)的對(duì)象來處理aSelector囚枪,則應(yīng)該調(diào)用父類的實(shí)現(xiàn)來返回結(jié)果派诬。

使用這個(gè)方法通常是在對(duì)象內(nèi)部,可能還有一系列其它對(duì)象能處理該消息链沼,我們便可借這些對(duì)象來處理消息并返回千埃,這樣在對(duì)象外部看來,還是由該對(duì)象親自處理了這一消息忆植。如下代碼所示:

@interface SUTRuntimeMethodHelper : NSObject

- (void)method2;

@end

@implementation SUTRuntimeMethodHelper

- (void)method2 {
    NSLog(@"%@, %p", self, _cmd);
}

@end

#pragma mark -

@interface SUTRuntimeMethod () {
    SUTRuntimeMethodHelper *_helper;
}

@end    

@implementation SUTRuntimeMethod

+ (instancetype)object {
    return [[self alloc] init];
}

- (instancetype)init {
    self = [super init];
    if (self != nil) {
        _helper = [[SUTRuntimeMethodHelper alloc] init];
    }

    return self;
}

- (void)test {
    [self performSelector:@selector(method2)];
}

- (id)forwardingTargetForSelector:(SEL)aSelector {

    NSLog(@"forwardingTargetForSelector");

    NSString *selectorString = NSStringFromSelector(aSelector);

// 將消息轉(zhuǎn)發(fā)給_helper來處理
if ([selectorString isEqualToString:@"method2"]) {
    return _helper;
}

    return [super forwardingTargetForSelector:aSelector];
}

@end

這一步合適于我們只想將消息轉(zhuǎn)發(fā)到另一個(gè)能處理該消息的對(duì)象上放可。但這一步無法對(duì)消息進(jìn)行處理,如操作消息的參數(shù)和返回值朝刊。

完整消息轉(zhuǎn)發(fā)

如果在上一步還不能處理未知消息耀里,則唯一能做的就是啟用完整的消息轉(zhuǎn)發(fā)機(jī)制了。此時(shí)會(huì)調(diào)用以下方法:

- (void)forwardInvocation:(NSInvocation *)anInvocation

運(yùn)行時(shí)系統(tǒng)會(huì)在這一步給消息接收者最后一次機(jī)會(huì)將消息轉(zhuǎn)發(fā)給其它對(duì)象拾氓。對(duì)象會(huì)創(chuàng)建一個(gè)表示消息的NSInvocation對(duì)象冯挎,把與尚未處理的消息 有關(guān)的全部細(xì)節(jié)都封裝在anInvocation中,包括selector咙鞍,目標(biāo)(target)和參數(shù)房官。我們可以在forwardInvocation 方法中選擇將消息轉(zhuǎn)發(fā)給其它對(duì)象。

forwardInvocation:方法的實(shí)現(xiàn)有兩個(gè)任務(wù):

  1. 定位可以響應(yīng)封裝在anInvocation中的消息的對(duì)象续滋。這個(gè)對(duì)象不需要能處理所有未知消息翰守。

  2. 使用anInvocation作為參數(shù),將消息發(fā)送到選中的對(duì)象疲酌。anInvocation將會(huì)保留調(diào)用結(jié)果蜡峰,運(yùn)行時(shí)系統(tǒng)會(huì)提取這一結(jié)果并將其發(fā)送到消息的原始發(fā)送者。

不過朗恳,在這個(gè)方法中我們可以實(shí)現(xiàn)一些更復(fù)雜的功能湿颅,我們可以對(duì)消息的內(nèi)容進(jìn)行修改,比如追回一個(gè)參數(shù)等粥诫,然后再去觸發(fā)消息油航。另外,若發(fā)現(xiàn)某個(gè)消息不應(yīng)由本類處理怀浆,則應(yīng)調(diào)用父類的同名方法谊囚,以便繼承體系中的每個(gè)類都有機(jī)會(huì)處理此調(diào)用請(qǐng)求怕享。

還有一個(gè)很重要的問題,我們必須重寫以下方法:

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector

消息轉(zhuǎn)發(fā)機(jī)制使用從這個(gè)方法中獲取的信息來創(chuàng)建NSInvocation對(duì)象秒啦。因此我們必須重寫這個(gè)方法,為給定的selector提供一個(gè)合適的方法簽名搀玖。

完整的示例如下所示:

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
    NSMethodSignature *signature = [super methodSignatureForSelector:aSelector];

if (!signature) {
    if ([SUTRuntimeMethodHelper instancesRespondToSelector:aSelector]) {
        signature = [SUTRuntimeMethodHelper instanceMethodSignatureForSelector:aSelector];
    }
}

return signature;
}

- (void)forwardInvocation:(NSInvocation *)anInvocation {
    if ([SUTRuntimeMethodHelper             instancesRespondToSelector:anInvocation.selector]) {
    [anInvocation invokeWithTarget:_helper];
}
}

NSObject的forwardInvocation:方法實(shí)現(xiàn)只是簡單調(diào)用了doesNotRecognizeSelector:方法余境,它不會(huì)轉(zhuǎn)發(fā)任何消息。這樣灌诅,如果不在以上所述的三個(gè)步驟中處理未知消息芳来,則會(huì)引發(fā)一個(gè)異常。

從某種意義上來講猜拾,forwardInvocation:就像一個(gè)未知消息的分發(fā)中心即舌,將這些未知的消息轉(zhuǎn)發(fā)給其它對(duì)象】嫱啵或者也可以像一個(gè)運(yùn)輸站一樣將所有未知消息都發(fā)送給同一個(gè)接收對(duì)象顽聂。這取決于具體的實(shí)現(xiàn)。

消息轉(zhuǎn)發(fā)與多重繼承

回過頭來看第二和第三步盯仪,通過這兩個(gè)方法我們可以允許一個(gè)對(duì)象與其它對(duì)象建立關(guān)系紊搪,以處理某些未知消息,而表面上看仍然是該對(duì)象在處理消息全景。通過這 種關(guān)系耀石,我們可以模擬“多重繼承”的某些特性,讓對(duì)象可以“繼承”其它對(duì)象的特性來處理一些事情爸黄。不過滞伟,這兩者間有一個(gè)重要的區(qū)別:多重繼承將不同的功能 集成到一個(gè)對(duì)象中,它會(huì)讓對(duì)象變得過大炕贵,涉及的東西過多梆奈;而消息轉(zhuǎn)發(fā)將功能分解到獨(dú)立的小的對(duì)象中,并通過某種方式將這些對(duì)象連接起來称开,并做相應(yīng)的消息轉(zhuǎn) 發(fā)鉴裹。

不過消息轉(zhuǎn)發(fā)雖然類似于繼承,但NSObject的一些方法還是能區(qū)分兩者钥弯。如respondsToSelector:和isKindOfClass:只能用于繼承體系径荔,而不能用于轉(zhuǎn)發(fā)鏈。便如果我們想讓這種消息轉(zhuǎn)發(fā)看起來像是繼承脆霎,則可以重寫這些方法总处,如以下代碼所示:

- (BOOL)respondsToSelector:(SEL)aSelector   {
   if ( [super respondsToSelector:aSelector] )
            return YES;     
   else {
             /* Here, test whether the aSelector message can
              *            
              * be forwarded to another object and whether that  
              *            
              * object can respond to it. Return YES if it can.  
              */      
   }
   return NO;  
}

這些東西我們只要了解就好,在開發(fā)中用到的不多

順便在這里說一下 objc中前面文章提到的數(shù)據(jù)類型
typedef struct objc_category *Category;

struct objc_category {
    char *category_name                          OBJC2_UNAVAILABLE; // 分類名
    char *class_name                             OBJC2_UNAVAILABLE; // 分類所    屬的類名
struct objc_method_list *instance_methods    OBJC2_UNAVAILABLE; // 實(shí)例方法列表
struct objc_method_list *class_methods       OBJC2_UNAVAILABLE; // 類方法列表
struct objc_protocol_list *protocols         OBJC2_UNAVAILABLE; // 分類所實(shí)現(xiàn)的協(xié)議列表
}

這是分類的結(jié)構(gòu)體 和類是不是很相似啊?哈哈

我們?cè)賮砜纯磪f(xié)議的struct

typedef struct objc_object Protocol;

簡單明了 大家一看,這不就是對(duì)象嘛

 struct objc_object {
    Class isa  OBJC_ISA_AVAILABILITY; //實(shí)例對(duì)象擁有指向類的指針
    };

class isa 指向了實(shí)現(xiàn)協(xié)議的類..(自然也將協(xié)議中的方法在實(shí)現(xiàn)的類中可以找到)

runtime.h 提供了很多接口讓開發(fā)者靈活使用,有對(duì)類的,對(duì)對(duì)象的,對(duì)屬性,方法的.(分類的東西已經(jīng)包含在類中),對(duì)協(xié)議的

我們可以在程序中動(dòng)態(tài)產(chǎn)生 繼承 改變 注冊(cè) 獲得 銷毀 各個(gè)我門想要操作

參考 apple runtime

最有趣又著名的莫過于sclector swizzing

這就是非常有用的的hook....
下一篇再講

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市睛蛛,隨后出現(xiàn)的幾起案子鹦马,更是在濱河造成了極大的恐慌胧谈,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件荸频,死亡現(xiàn)場(chǎng)離奇詭異菱肖,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)旭从,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門稳强,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人和悦,你說我怎么就攤上這事退疫。” “怎么了鸽素?”我有些...
    開封第一講書人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵褒繁,是天一觀的道長。 經(jīng)常有香客問我馍忽,道長棒坏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任遭笋,我火速辦了婚禮俊抵,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘坐梯。我一直安慰自己徽诲,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開白布吵血。 她就那樣靜靜地躺著谎替,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蹋辅。 梳的紋絲不亂的頭發(fā)上钱贯,一...
    開封第一講書人閱讀 51,679評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音侦另,去河邊找鬼秩命。 笑死,一個(gè)胖子當(dāng)著我的面吹牛褒傅,可吹牛的內(nèi)容都是我干的弃锐。 我是一名探鬼主播,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼殿托,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼霹菊!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起支竹,我...
    開封第一講書人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤旋廷,失蹤者是張志新(化名)和其女友劉穎鸠按,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體饶碘,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡目尖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了扎运。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瑟曲。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖绪囱,靈堂內(nèi)的尸體忽然破棺而出测蹲,到底是詐尸還是另有隱情莹捡,我是刑警寧澤鬼吵,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站篮赢,受9級(jí)特大地震影響齿椅,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜启泣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一涣脚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧寥茫,春花似錦遣蚀、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至弄喘,卻和暖如春玖喘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蘑志。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來泰國打工累奈, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人急但。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓澎媒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親波桩。 傳聞我的和親對(duì)象是個(gè)殘疾皇子旱幼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

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

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,719評(píng)論 0 9
  • 參考鏈接: http://www.cnblogs.com/ioshe/p/5489086.html 簡介 Runt...
    樂樂的簡書閱讀 2,135評(píng)論 0 9
  • 我們常常會(huì)聽說 Objective-C 是一門動(dòng)態(tài)語言突委,那么這個(gè)「動(dòng)態(tài)」表現(xiàn)在哪呢柏卤?我想最主要的表現(xiàn)就是 Obje...
    Ethan_Struggle閱讀 2,195評(píng)論 0 7
  • 本文詳細(xì)整理了 Cocoa 的 Runtime 系統(tǒng)的知識(shí)冬三,它使得 Objective-C 如虎添翼,具備了靈活的...
    lylaut閱讀 800評(píng)論 0 4
  • 本文轉(zhuǎn)載自:http://yulingtianxia.com/blog/2014/11/05/objective-...
    ant_flex閱讀 763評(píng)論 0 1