亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

Objective-C 消息轉發機制

2019-11-07 23:11:54
字體:
來源:轉載
供稿:網友

一圖勝千言,習慣性的先來一張圖以便對消息轉發有個整體的把握

運行時系統庫方法查詢流程圖

運行時系統庫方法查詢

對于對象無法處理的消息,如果不做轉發處理的話,程序最終會調用NSObjective的doesNotRecognizeSelector:消息將程序crash掉。

Objective-C提供了兩種消息轉發選項

快速轉發:NSObject類的子類A可以通過重寫NSObject類的forwardingTargetForSelector:方法,將A的實例無法識別的消息轉發給目標對象B,從而實現快速轉發。該技巧就像是將對象的實現代碼與轉發對象合并到一起。這類似于實現的多繼承行為。如果你有一個定了對象 能夠消化哪些消息的目標類,這個技巧可以取得很好的效果標準(完整)轉發:NSObject類的子類A可以通過重寫NSObject類的forwardInvocation:方法,實現標準轉發。該技巧可以通過methodSignatureForSelector:方法獲取一個NSInvocation對象,能獲取消息的全部內容(包含目標,方法名,和參數)。

如果你擁有了一個定義了對象能夠消化哪些消息的目標類,快速轉發可以取得很好的效果。如果你沒有這樣目標類或想要執行其他處理過程(如記錄日志并‘吞下’消息),就應該使用完整轉發。

寫了一大推字感覺很抽象,下面來點干貨

下面我要把Test實例的logName消息轉發給Target實例,代碼如下 Test頭文件

//// Test.h// ForwardMsg//// Created by 孫磊 on 2017/2/25.// Copyright ? 2017年 孫磊. All rights reserved.//#import <Foundation/Foundation.h>@interface Test : NSObject-(void)logName;@end

Test實現文件

//// Test.m// ForwardMsg//// Created by 孫磊 on 2017/2/25.// Copyright ? 2017年 孫磊. All rights reserved.//#import "Test.h"#import "Target.h"#import <objc/runtime.h>@implementation Test{ Target *mTarget;}- (instancetype)init{ self = [super init]; if (self) { //創建目標對象 mTarget = [Target new]; } return self;}#if 0//當一個對象無法識別消息后,會執行resolveInstanceMethod或者resolveClassMethod方法//如果不想進行消息轉發,可以在此方法中動態添加消息來做處理//如果不重寫此方法或者此方法返回NO,系統會執行forwardingTargetForSelector進行快速轉發+ (BOOL)resolveInstanceMethod:(SEL)sel{ if(sel == @selector(logName)){ //第四個參數詳解地址 https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html //v代表返回類型為void //@代表一個對象 //:代表一個selector //因為OC中的每個方法都有默認的兩個參數sel 和 selector,所以一般都是v@: class_addMethod([self class],sel,(IMP)dynamicMethodIMP,"v@:"); return YES; } return [super resolveInstanceMethod:sel];}//萬年備胎void dynamicMethodIMP(id self, SEL _cmd){ //對無法識別的消息做處理 NSLog(@"該對象無法識別 %@ 方法------%s", NSStringFromSelector(_cmd),__func__);}#else /***************==========1、快速消息轉發,快速轉發只可以獲取到方法簽名==========*******************/-(id)forwardingTargetForSelector:(SEL)aSelector{ NSLog(@"%s",__func__); if ([mTarget respondsToSelector:aSelector]) { //目標對象有對應的處理方法,則就會快速消息轉發,不會再執行完整消息轉發了 return mTarget; } //目標對象也沒有對應的方法,此時系統會執行forwardInvocation進行完整消息轉發 return nil;}/***********=============2、標準(完整)消息轉發,完整消息轉發,可以獲取方法簽名,參數等詳細信息==========*********///返回一個完整的方法簽名,提供給forwardInvocation以便完整轉發消息-(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{ NSMethodSignature* signature = [super methodSignatureForSelector:aSelector]; if (!signature) signature = [mTarget methodSignatureForSelector:aSelector]; return signature;}-(void)forwardInvocation:(NSInvocation *)anInvocation{ NSLog(@"%s-----完整消息轉發------",__func__); SEL invSEL = anInvocation.selector; if ([mTarget respondsToSelector:invSEL]){ //利用forwardInvocation方法來重新指定消息處理對象 [anInvocation invokeWithTarget:mTarget]; } else { [self doesNotRecognizeSelector:invSEL]; }}#endif@end

目標文件的頭文件

//// Target.h// ForwardMsg//// Created by 孫磊 on 2017/2/25.// Copyright ? 2017年 孫磊. All rights reserved.//#import <Foundation/Foundation.h>@interface Target : NSObject-(void)logName;@end

目標文件的實現文件

//// Target.m// ForwardMsg//// Created by 孫磊 on 2017/2/25.// Copyright ? 2017年 孫磊. All rights reserved.//#import "Target.h"@implementation Target-(void)logName{ NSLog(@"我是備用方法---%s",__func__);}@end

推薦一個國外大大利用消息轉發避免后臺返回null或者NSNull而引起的奔潰問題,用法也很簡單,直接把NullSafe.m拖到項目中即可,該文件會在運行時自動加載


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
少妇高潮久久久久久潘金莲| 欧洲亚洲免费视频| 欧美极品xxxx| 成人精品久久av网站| 亚洲韩国欧洲国产日产av| 日韩精品免费电影| 成人国产精品免费视频| 26uuu另类亚洲欧美日本一| 欧美日韩亚洲一区二区三区| 国产精品久久久久久搜索| 国产91精品不卡视频| 夜夜嗨av一区二区三区免费区| 91精品国产综合久久久久久久久| 亚洲视频一区二区三区| 最近2019中文字幕一页二页| 欧美另类老肥妇| 亚洲欧美成人在线| 欧美黑人性视频| 日韩中文字幕在线免费观看| 亚洲人成电影网站色…| 日韩视频在线免费观看| 国产精品v片在线观看不卡| 久久久久久久久电影| 午夜精品一区二区三区在线视| 欧美日韩亚洲天堂| 91中文字幕在线| 亚洲精品视频播放| 精品丝袜一区二区三区| 国产欧美va欧美va香蕉在| 美女少妇精品视频| 亚洲精品永久免费| 欧美一区二区影院| 一个人看的www欧美| 欧美成人免费一级人片100| 久久精品99久久香蕉国产色戒| 欧美老妇交乱视频| 欧美日韩精品在线视频| 国产成人涩涩涩视频在线观看| 欧美成人免费在线观看| 精品国产鲁一鲁一区二区张丽| 久久中国妇女中文字幕| 国产aⅴ夜夜欢一区二区三区| 精品毛片网大全| 国产一区二区视频在线观看| 亚洲成色www8888| 亚洲国产精久久久久久| 日韩一级裸体免费视频| www国产91| 成人亚洲欧美一区二区三区| 欧美成人精品在线| 久色乳综合思思在线视频| 欧美极品美女电影一区| 欧美一区二区三区免费视| 色妞一区二区三区| 国产精品视频不卡| 亚洲国产小视频在线观看| 亚洲欧美日韩中文在线| 精品久久久久久久久中文字幕| 91精品国产网站| 国产精品久久久久久久一区探花| 2019亚洲男人天堂| 中文字幕亚洲一区二区三区五十路| 蜜臀久久99精品久久久无需会员| 55夜色66夜色国产精品视频| 国产精品日日做人人爱| 国产精品视频色| 国内精品小视频| 欧美激情欧美激情在线五月| 最近的2019中文字幕免费一页| 日韩视频中文字幕| 亚洲天堂av在线播放| 亚洲第一天堂无码专区| 亚洲人成电影网站色| 欧美国产精品人人做人人爱| 国产精品午夜一区二区欲梦| 秋霞成人午夜鲁丝一区二区三区| 日韩在线观看免费全集电视剧网站| 国产精品第1页| 精品久久久久久久大神国产| 日韩国产激情在线| 久久影院免费观看| 久热国产精品视频| 久久天堂av综合合色| 国产ts人妖一区二区三区| 毛片精品免费在线观看| 亚洲欧美日韩精品久久| 久久精品一本久久99精品| 亚洲午夜激情免费视频| 91精品视频专区| 欧美激情成人在线视频| 国产精品视频精品| 国产午夜精品麻豆| 久久九九亚洲综合| 国产精品国产亚洲伊人久久| 在线播放日韩欧美| 亚洲美女性生活视频| 欧美日韩国产二区| 亚洲第一精品电影| 久久99久国产精品黄毛片入口| 欧美疯狂xxxx大交乱88av| 亚州国产精品久久久| 精品一区二区三区四区在线| 一区二区三区精品99久久| 一区二区三区视频在线| 亚洲毛片一区二区| 亚洲第一免费网站| 欧美裸体xxxx| 欧美日韩一区二区免费在线观看| 欧美亚洲激情在线| 国产精品嫩草影院一区二区| 国产精品久久久久一区二区| 久久久久久久激情视频| 国产精品99久久久久久白浆小说| 国产色视频一区| 国内精品中文字幕| 亚洲一品av免费观看| 亚洲影院色在线观看免费| 97超级碰碰碰| 国产一区二区三区在线观看视频| 亚洲国产天堂久久综合网| 国产精品久久久久不卡| 国产亚洲欧美另类中文| 国产欧美日韩综合精品| 91精品国产91久久久久| 日韩精品视频免费在线观看| 精品一区二区三区四区在线| 国产精品日本精品| 日韩精品日韩在线观看| 久久精品视频播放| 久久亚洲精品网站| 国产一区玩具在线观看| 亚洲国产高潮在线观看| 欧美一级片在线播放| 欧美黑人xxxx| 亚洲精品suv精品一区二区| 国产欧美日韩精品在线观看| 亚洲欧美日韩视频一区| 亚洲国产精品电影在线观看| 操日韩av在线电影| 欧美激情一区二区三区成人| 久久人人97超碰精品888| 粗暴蹂躏中文一区二区三区| 日本一区二三区好的精华液| 久久久久久久999精品视频| 一本一本久久a久久精品综合小说| 欧美大片免费看| 国产精品尤物福利片在线观看| 青青精品视频播放| 国产香蕉97碰碰久久人人| 国产精品成人一区二区三区吃奶| 日韩av在线网址| 色偷偷噜噜噜亚洲男人的天堂| 亚洲石原莉奈一区二区在线观看| 亚洲色在线视频| 神马久久桃色视频| 日韩精品久久久久久福利| 精品久久国产精品| 精品亚洲国产视频| 福利视频第一区| 大胆欧美人体视频| 亚洲韩国日本中文字幕| 亚洲第一区中文99精品| 欧美激情极品视频| 69视频在线播放|