runtime使用之消息發(fā)送的本質(zhì)

前言

  • 本章主要是描述如何簡(jiǎn)單使用runtime,runtime蘋果官方是開(kāi)源的,想要了解更多的朋友可以直接去看官方源碼.

一, runtime簡(jiǎn)介

  • runtime簡(jiǎn)稱為運(yùn)行時(shí),OC是運(yùn)行時(shí)機(jī)制,比如OC的消息機(jī)制.
  • 關(guān)于C語(yǔ)言,我們都知道它是在編譯的時(shí)候就會(huì)決定去調(diào)用哪個(gè)函數(shù).
  • 但是,OC是在編譯的時(shí)候并不能調(diào)用函數(shù),而是在運(yùn)行的時(shí)候才會(huì)真正的去根據(jù)函數(shù)名去找到并調(diào)用對(duì)應(yīng)的函數(shù)的方法.
  • OC與C語(yǔ)言區(qū)別之一:OC是運(yùn)行時(shí)機(jī)制,C語(yǔ)言是編譯時(shí)機(jī)制.比如說(shuō):在OC中,只要你聲明了函數(shù),但是沒(méi)有去實(shí)現(xiàn)它,在編譯的時(shí)候是不會(huì)報(bào)錯(cuò)的,只有在運(yùn)行的時(shí)候才會(huì)報(bào)錯(cuò).但是,C語(yǔ)言只要你沒(méi)有聲明函數(shù),如果直接去實(shí)現(xiàn)方法的話,它會(huì)在編譯的時(shí)候就會(huì)報(bào)錯(cuò).

二, runtime的作用

1, 發(fā)送消息
  • 眾所周知, OC是消息機(jī)制,其本質(zhì)就是讓對(duì)象發(fā)送消息,計(jì)算機(jī)是無(wú)法讀取OC語(yǔ)言,其本質(zhì)是將OC語(yǔ)言通過(guò)runtime轉(zhuǎn)化為C語(yǔ)言,最后轉(zhuǎn)為二進(jìn)制.
  • 使用runtime的前提是需要導(dǎo)入#import< objc/message.h>
    或者是#imaport< objc/runtime.h >
  • 只有對(duì)象才能發(fā)送消息,在runtime中發(fā)送消息的方法是:objc_msgSend, runtime中的方法大多都是以objc開(kāi)頭的.

三, runtime的使用場(chǎng)景

  • 使用場(chǎng)景1 : runtime的消息機(jī)制,自己寫自己的框架
  • 使用場(chǎng)景2 : 如果我們想要去調(diào)用別的框架或者是系統(tǒng)中沒(méi)有暴露出來(lái)的方法.
  • 使用場(chǎng)景3 : 如果我們想要研究系統(tǒng)內(nèi)部有哪些私有方法, 有哪些私有屬性.
  • 使用場(chǎng)景4 : 如果我們想要獲取到系統(tǒng)自帶的控件的子控件
  • 實(shí)現(xiàn)原理 : 根據(jù)方法名去找對(duì)應(yīng)的方法實(shí)現(xiàn),具體例子如下:
 // 新建一個(gè)學(xué)生類WGStudent, 在類中什么一個(gè)對(duì)象方法和類方法.
 #import <Foundation/Foundation.h>

WGStudent.h文件
@interface WGStudent : NSObject

  // - (void)study;
  // + (void)eat;

@end

WGStudent.m文件
#import "WGStudent.h"

@implementation WGStudent

- (void)study {
    NSLog(@"學(xué)習(xí)數(shù)學(xué)");
}

+ (void)eat {
    NSLog(@"吃飯");
}
@end
  • 注意 : 這里新建WGStudent類的目的主要是用于解釋類的調(diào)用原理
#import "ViewController.h"
#import "WGStudent.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

//  對(duì)象發(fā)送消息
    // OC中調(diào)用對(duì)象方法
    WGStudent *student = [[WGStudent alloc] init];

    [student study];

    // [student study]的本質(zhì)就是讓對(duì)象發(fā)送消息
    objc_msgSend(student @selecter(study));

// 類調(diào)用對(duì)象方法,發(fā)送消息
// 調(diào)用類方法的方式:兩種

    // 第一種通過(guò)類名調(diào)用
    [student eat];
    // 第二種通過(guò)類對(duì)象調(diào)用
    [[student class] eat];

    // 用類名調(diào)用類方法,底層會(huì)自動(dòng)把類名轉(zhuǎn)換成類對(duì)象調(diào)用
    // 本質(zhì):讓類對(duì)象發(fā)送消息
    objc_msgSend([student class], @selector(eat));
}

@end

  • 特別注意 : 如果你這里就運(yùn)行程序,程序會(huì)直接報(bào)錯(cuò),所以這里需要做兩步操作.
  • 1, 判斷是否導(dǎo)入#import< objc/message.h> 或者 #imaport< objc/runtime.h >
  • 2, 進(jìn)入工程 -> Build Settting -> msg -> No(不嚴(yán)格檢測(cè)發(fā)送消息的調(diào)用)

四, 解析創(chuàng)建一個(gè)對(duì)象時(shí),如何使用runtime轉(zhuǎn)化OC的.

// 解析創(chuàng)建對(duì)象過(guò)程
WGStudent *student = [[WGStudent alloc] init];

// 1, 分配存儲(chǔ)空間
    WGStudent *student = [WGStudent alloc];
--> 使用runtime創(chuàng)建對(duì)象
    objc_msgSend([WGStudent class], @selector(alloc));

// 2, 初始化
    student = [student init];
--> 使用runtime進(jìn)行初始化
    student = objc_msgSend(student, @selector(init));

// 3, 調(diào)用對(duì)象方法
    [student study];
--> 使用runtime調(diào)用方法
    objc_msgSend(student, @selector(study));

  • 知識(shí)拓展 :

  • 1, xcode6開(kāi)始,蘋果不推薦我們使用runtime,把很多函數(shù)的參數(shù)注釋.

  • 2, xcode6做了一些事情,導(dǎo)致不能調(diào)用objc_msgSend

  • 注意點(diǎn):把函數(shù)名轉(zhuǎn)換成某個(gè)函數(shù)指針,一定要用括號(hào)包住,在調(diào)用


    ((NSObject * (*)(id, SEL))objc_msgSend)(self,@selector(eat));
    objc_msgSend(self,@selector(eat));

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

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

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 2,041評(píng)論 0 9
  • 參考鏈接: http://www.cnblogs.com/ioshe/p/5489086.html 簡(jiǎn)介 Runt...
    樂(lè)樂(lè)的簡(jiǎn)書閱讀 2,247評(píng)論 0 9
  • 對(duì)于從事 iOS 開(kāi)發(fā)人員來(lái)說(shuō),所有的人都會(huì)答出【runtime 是運(yùn)行時(shí)】什么情況下用runtime?大部分人能...
    夢(mèng)夜繁星閱讀 3,804評(píng)論 7 64
  • 詩(shī)詞歌賦篇章中曾記載“又是人間四月天,陰曹路上是何年?碑前片片飛花亂,眼底絲絲淚血煎.”誰(shuí)又知喚兒聲聲在耳邊,轉(zhuǎn)身...
    城磚上的印記閱讀 1,349評(píng)論 0 0
  • 九月就看到這部片子(剩者為王),沒(méi)想到首映居然是我生日當(dāng)天,對(duì)男神的好感又飆升了一級(jí),上個(gè)月開(kāi)始一直被朋友們提醒6...
    shally925閱讀 341評(píng)論 0 1

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