成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

iOS消息轉發機制Demo解析

移動開發
假設說我們聲明一個類, 初始化對象, 并且在此類聲明一個方法, 調用方法的時候底層是怎么處理的呢? 今天我們來簡單模擬測試, 來看道理發生了什么?

假設說我們聲明一個類, 初始化對象, 并且在此類聲明一個方法, 調用方法的時候底層是怎么處理的呢? 今天我們來簡單模擬測試, 來看道理發生了什么

以下是調用方法處理的方案圖, 按照方案順序去處理 

以下是系統方法 

  1. //消息轉發 
  2. //- (id)forwardingTargetForSelector:(SEL)aSelector OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); 
  3. //標準的消息轉發 
  4. //- (void)forwardInvocation:(NSInvocation *)anInvocation OBJC_SWIFT_UNAVAILABLE(""); 
  5. //- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector OBJC_SWIFT_UNAVAILABLE(""); 
  6. // 
  7. //動態方法解析 
  8. //+ (BOOL)resolveClassMethod:(SEL)sel OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); 
  9. //+ (BOOL)resolveInstanceMethod:(SEL)sel OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0); 

Demo解析

基礎步驟

創建類, Person類, 聲明方法, 并且在ViewController進行初始化調用 

  1. VC中 
  2. Person *person = [Person new]; 
  3. [person run]; 
  4. Person類中 
  5. - (void)run;//沒有實現 

此時運行是不是會報錯呢? 就是這個常見的錯誤

“ - [Person run]: unrecognized selector sent to instance 0x600000008310’ “

那么這樣做到底發生了什么? 做了哪些事情? 我們一步步來剖析

動態測試

在Presenter類中, 寫動態方法 

  1. + (BOOL)resolveInstanceMethod:(SEL)sel{ 
  2. NSLog(@"sel = %@",NSStringFromSelector(sel)); 
  3. return [super resolveInstanceMethod:sel]; 

再次運行Demo就會走到這個方法中, 也就是我們所指的方案1, 此時打印出來的scl為” 消息轉發機制Demo[41829:4186268] sel = run “

解析模擬 

  1. + (BOOL)resolveInstanceMethod:(SEL)sel{ 
  2. NSLog(@"sel = %@",NSStringFromSelector(sel)); 
  3. //1.判斷沒有實現方法, 那么我們就是動態添加一個方法 
  4. if (sel == @selector(run:)) { 
  5. class_addMethod(self, sel, (IMP)newRun, "v@:@:"); 
  6. return YES; 
  7. return [super resolveInstanceMethod:sel]; 

聲明函數 

  1. void newRun(id self,SEL sel,NSString *str) { 
  2. NSLog(@"---runok---%@",str); 

溫馨小提示, 動態添加方法參數意譯 : //將要添加方法的類/sel名/IMP函數指針<添加函數>, 官方文檔其實是有解釋的

此時我們再次運行, 那么打印結果就來了” 消息轉發機制Demo[43269:4212899] —runok—ok跑 “, 這樣的話我們就解決掉了報錯這個問題

消息轉發重定向測試

此時我們新創建一個類Mbxb, 此時我們還是重新寫一個同名字的方法run方法, 并且進行實現 

  1. - (void)run{ 
  2. NSLog(@"---Mbxbrunok---"); 

解析

此時有兩個同樣的方法, 我們重新在Person類中

來實現方法 

  1. - (id)forwardingTargetForSelector:(SEL)aSelector{ 
  2. NSLog(@"aSelector = %@",NSStringFromSelector(aSelector)); 
  3. return [super forwardingTargetForSelector:aSelector]; 

此時運行測試, 動態測試輸出” 消息轉發機制Demo[45875:4255869] sel = run “, 消息轉發重定向輸出” 消息轉發機制Demo[45875:4255869] —Mbxbrunok— “, 同樣也可以找見方法run

當我們進行處理 

  1. - (id)forwardingTargetForSelector:(SEL)aSelector{ 
  2. NSLog(@"aSelector = %@",NSStringFromSelector(aSelector)); 
  3. return [[Mbxb alloc]init]; 

那么此時運行成功輸出, “ —Mbxbrunok— “

生成方法簽名轉發消息

此時我們在Person類中, 生成方法簽名 

  1. - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector OBJC_SWIFT_UNAVAILABLE(""){ 
  2. //轉化字符 
  3. NSString *sel = NSStringFromSelector(aSelector); 
  4. //判斷, 手動生成簽名 
  5. if([sel isEqualToString:@"run"]){ 
  6. return [NSMethodSignature signatureWithObjCTypes:"v@:"]; 
  7. }else
  8. return [super methodSignatureForSelector:aSelector]; 

拿到簽名 

  1. - (void)forwardInvocation:(NSInvocation *)anInvocation OBJC_SWIFT_UNAVAILABLE(""){ 
  2. NSLog(@"---%@---",anInvocation); 
  3. return [super forwardInvocation:anInvocation]; 

此時我們的po的簽名輸出為” return value: {v} void target: {@} 0x600000016ba0 selector: {:} run “

拿到消息轉發簽名 

  1. - (void)forwardInvocation:(NSInvocation *)anInvocation OBJC_SWIFT_UNAVAILABLE(""){ 
  2. NSLog(@"---%@---",anInvocation); 
  3. //取到消息 
  4. SEL seletor = [anInvocation selector]; 
  5. //轉發 
  6. Mbxb *bxb = [[Mbxb alloc]init]; 
  7. if([bxb respondsToSelector:seletor]){ 
  8. //調用對象,進行轉發 
  9. [anInvocation invokeWithTarget:bxb]; 
  10. }else
  11. return [super forwardInvocation:anInvocation]; 

小細節: 拋出異常

假如說我們沒有這個方法, 同樣是遇到會崩潰的問題

我們這里來進行一個異常處理 

  1. - (void)doesNotRecognizeSelector:(SEL)aSelector{ 
  2. NSString *selStr = NSStringFromSelector(aSelector); 
  3. NSLog(@"%@不存在",selStr); 

我們可以在這個異常處理中一些處理, 比如說彈框

總結

對于消息轉發機制, 我們重新來梳理一下Demo解析思路

還是三個方案, 按順序來走

  1. 動態方法解析
  2. 消息轉發重定向
  3. 生成方法簽名
  4. 拿到簽名轉發消息
  5. 細節處理, 拋出異常
  6. 最后獻上一張邏輯圖 

好了, 給大家這個簡單demo, 當然在代碼中也寫了注釋, 可以去我的git下載, 歡迎star

責任編輯:未麗燕 來源: Oboe_b
相關推薦

2023-10-13 10:44:35

OC消息發送

2024-09-25 08:32:05

2014-03-04 15:28:32

iOS開發消息傳遞機制

2011-05-31 11:55:00

Android 消息機制

2011-02-21 15:17:45

Qmail

2016-03-02 09:34:03

runtime消息ios開發

2013-04-11 12:40:16

Android消息機制

2013-12-16 09:44:01

OpenDayLighSDN網絡轉發

2011-07-01 15:04:49

Qt 內省

2024-11-11 13:28:11

RocketMQ消息類型FIFO

2024-10-29 08:34:27

RocketMQ消息類型事務消息

2011-08-02 18:07:03

iPhone 內省 Cocoa

2017-08-17 15:13:52

PostgreSQL MVCC機制

2011-11-23 09:39:33

JavaClassLOader機制

2011-04-07 17:54:22

Policing

2010-08-13 14:19:44

Flex綁定機制

2011-04-07 17:27:52

Policing

2011-04-07 17:43:37

Shapping

2011-04-07 17:39:57

Shapping

2024-11-14 09:10:13

消費者RocketMQ負載均衡
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美a∨| 欧美精品一区二区三区蜜桃视频 | 日本在线视 | 欧美 日韩 亚洲91麻豆精品 | 免费视频一区二区 | 中文字幕在线视频一区二区三区 | 久精品久久 | 日韩av一二三区 | 久久久久一区二区三区 | 日韩国产中文字幕 | 五月天婷婷丁香 | 日本亚洲一区二区 | 在线播放一区 | 亚洲视频精品在线 | 一本久久a久久精品亚洲 | 日韩一区中文字幕 | 婷婷色在线 | 狠狠伊人| 亚洲福利一区 | 中文字幕在线一区二区三区 | 日本一区二区三区免费观看 | 国产亚洲欧美在线视频 | 国产亚洲网站 | aaa在线| 亚洲免费人成在线视频观看 | 日韩不卡一二区 | 91传媒在线观看 | 日韩第1页 | 伊人久操| 久久久高清 | 在线一区二区三区 | 欧美人妖网站 | 久久com| 亚洲视频区 | 天天摸天天干 | 国产精品视频在线观看 | 欧美www在线| 成人免费大片黄在线播放 | 久久av一区二区三区 | 在线观看黄免费 | 国产欧美日韩精品在线观看 |