iOS開發runtime學習:一:runtime簡介與runtime的消息機制

一:runtime簡介:也是面試必須會回答的部分面試

二:runtime的消息機制xcode

#import "ViewController.h"
#import <objc/message.h>
#import "Person.h"
/* 
 總結:
    1:
    runtime:必需要導入頭文件 <objc/message.h>,此頭文件中已經引入了<objc/runtime.h>
    任何方法調用本質:發送一個消息,用runtime發送消息.OC底層實現經過runtime實現
    驗證:方法調用,是否真的是轉換爲消息機制
    runtime都有一個前綴,誰的事情使用誰
 
 
    2:((NSObject *(*)(id, SEL))(void *)objc_msgSend)([NSObject class], @selector(alloc));
 
 此段代碼可簡化爲:objc_msgSend([NSObject class], @selector(alloc));,其中(NSObject *(*)(id, SEL))此爲一個函數指針,返回值類型爲NSObject *,參數爲(id, SEL)),id表明誰發送的消息 ,SEL:函數入口,發送什麼消息
 
 xcode6以前,蘋果運行使用objc_msgSend.並且有參數提示
 xcode6蘋果不推薦咱們使用runtime
 
    3:解決消息機制方法提示步驟
      查找build setting -> 搜索msg,設置爲NO,通常配置信息都在build setting中設置,build Phases通常是引入系統框架和設置參與編譯的.m文件,.h文件不參與編譯
      最終生成消息機制,編譯器作的事情
      最終代碼,須要把當前代碼從新編譯,用xcode編譯器,clang

 4:runtime:方法都是有前綴,誰的事情誰開頭
   開發中使用場景:
   須要用到runtime,消息機制
   1.裝逼
   2.不得不用runtime消息機制,能夠調用系統API中或是框架中的私有方法
 
 5:消息機制的調用過程:
  面試:
  方法調用流程
  怎麼去調用eat方法 ,對象方法:類對象的方法列表 類方法:元類中方法列表
  1.經過isa去對應的類中查找
  2.註冊方法編號
  3.根據方法編號去查找對應方法
  4.找到只是最終函數實現地址,根據地址去方法區調用對應函數
 
 過程:一個對象被初始化後,內部會有一個isa指針,指向類對象(類對象的方法列表),類對象中會有一個方法列表,此時會根據方法列表註冊方法編號,方法編號對應方法列表,根據方法編號查找對應的方法,找到的只是最終函數的實現地址,根據地址去內存中的方法區調用對應函數
 
 
 
 內存的5大區
 1.棧 2.堆 3.靜態區 4.常量區 5.方法區
 1.棧:不須要手動管理內存,自動管理
 2.堆,須要手動管理內存,本身去釋放
 
 
 
 
 */

@interface ViewController ()

@end

@implementation ViewController

/**
 *    1:objc_getClass("Person")表示得到類對象,sel_registerName("alloc")表示註冊一個方法
    2:調用eat:是對象調用eat,消息機制就是誰發送的什麼消息:objc_msgSend(p, @selector(eat));
 */
- (void)viewDidLoad {
    [super viewDidLoad];
    

//    Person *p = [Person alloc];
    Person *p = objc_msgSend(objc_getClass("Person"), sel_registerName("alloc"));
    
    
//    p = [p init];
    p = objc_msgSend(p, sel_registerName("init"));
    
    
    
    // 調用eat
//    [p eat];
    objc_msgSend(p, @selector(eat));
//    objc_msgSend(p, @selector(run:),20);
    
   
}


/**  
    1:一個對象的初始化方法可分解爲兩步:alloc 來開闢內存空間,init來初始化:id objc = [NSObject alloc];開闢內存空間的時候得到一個類對象,類對象在初始化獲得一個對象objc = [objc init];
 
    2:上述初始化的過程用runtime來實現:
 
       //id objc = [NSObject alloc];
        id objc = objc_msgSend([NSObject class], @selector(alloc));
        //objc = [objc init];
        objc = objc_msgSend(objc, @selector(init));
 *
 */
- (void)test
{
    //    id objc = [NSObject alloc];
    id objc = objc_msgSend([NSObject class], @selector(alloc));
    
    //    objc = [objc init];
    objc = objc_msgSend(objc, @selector(init));
}

@end

相關文章
相關標籤/搜索