国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

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

iOSRunTime的簡單使用

2019-11-14 18:10:13
字體:
來源:轉載
供稿:網友

1.根據指定規則根據runtime進行頁面選擇跳轉

        背景:要根據后臺返回的數據 進行選擇要跳轉到哪一個ViewController  

    

 // 這個規則肯定事先跟服務端溝通好,跳轉對應的界面需要對應的參數

    NSDictionary *userInfo = @{

                               @"class": @"HSFeedsViewController",

                               @": @{//類中所需要的參數

                                       @"ID": @"123",

                                       @"type": @"12"

                                       }

                               };

        思路:使用runtime去解決這個問題的思路就是 通過運行時 根據對應的類名去創建類以及類的屬性,這就需要和服務端去協商返回的數據形式 要類似: 

        實現:  這里使用了三個objc/runtime.h中函數分別是: 

 

(1)objc_getClass(const char *name)  即返回對應的類;

(2)objc_allocateClassPair(Class superClass,const char*name ,size_t extraBytes) 為對應的類設置父類,并根據父類和extraBytes(變量的字節數) 給這個類分配空間

(3)objc_registerClassPair(class) 注冊這個類

         通過這三個函數 創建類一個類

 

還有一個運行時函數  class_copyPropertyList(Class class,unsigned int *outCount) 

 

objc_property_t  class_copyPropertyList(Class class,unsigned int *outCount)    返回值為一個數組 數組中為對應的類的屬性列表 以此來對比類中是否含有當前屬性,從而通過KVC為類的屬性賦值.

 

2.修改系統類的方法實現

      背景:如果需求中要統計每個viewController 展示給用戶的次數,我們想到的就是在ViewController中添加對應的統計的代碼,但是會很麻煩,此時可以創建一個UI ViewController的分類更改底層中viewWillAppear的實現 這就用到runtime中method Swizzling (方法混合)

     實現:通過methodSwizzling 修改了UIViewController的@selector(viewWillAppear:)對應的函數指針,使他的實現指向了自定的方法

 

#import "UIViewController+Tracking.h"#import <objc/runtime.h> @implementation UIViewController (Tracking) + (void)load{        static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        Class  class  = [self class];        SEL originalSelector = @selector(viewWillAppear:);        SEL swizzlingSelector = @selector(swizzling__viewWillAppear:);        Method originMethod = class_getInstanceMethod(class, originalSelector);        Method swizzlingMethod = class_getInstanceMethod(class, swizzlingSelector);                //將 swizzlingMethod 中的實現過程添加到 originalSelector 這個方法中        BOOL didAddMethod = class_addMethod(class,originalSelector, method_getImplementation(swizzlingMethod), method_getTypeEncoding(swizzlingMethod));        if (didAddMethod) {            //用 originMethod中的實現 替換 swizzlingSelector這個方法中的實現 這樣原始的和自定義的方法都執行的時同一個實現過程            class_replaceMethod(class, swizzlingSelector, method_getImplementation(originMethod), method_getTypeEncoding(originMethod));        }else{//可能出現添加失敗的情況(比如 被添加的方法中已經存在了對應方法的實現 就會返回NO)            //將 originMethod 和 swizzlingMethod中的實現過程進行交換            method_exchangeImplementations(originMethod, swizzlingMethod);        }            });}/* 經過上面的  class_method 和 class_replaceMethod 或  method_exchangeImplementations 就實現了 //http://blog.jobbole.com/79580/ */ - (void)swizzling__viewWillAppear:(BOOL)animation{    [self swizzling__viewWillAppear:animation];    NSLog(@"swizzling_viewWillAppear");}

 

(1)通過兩個方法  class_addMethod class_replaceMethod這個方法實現方法Method這個結構體中 IMP對應的函數指針對應的函數實現進行添加 或者 替換SEL 代表了Method的名稱name,IMP代表函數指針 即為函數在內存中的開始位置

另外還有一些注意事項 為什么一定要寫在load中 還要寫在dispatch_once中,因為swilzzing method會影響代碼的整體狀態 甚至有可能改變程序的運行流程,要保證避免并發的競爭,而+load方法是在類初始化就進行了加載(這里不太明白具體原理)詳細參看下面鏈接

http://nshipster.com/method-swizzling/


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 托克托县| 宽城| 彩票| 德江县| 漠河县| 麦盖提县| 潮安县| 佛冈县| 商都县| 寻乌县| 石首市| 高安市| 淳化县| 宝丰县| 汶上县| 昭觉县| 和平区| 屏山县| 兴和县| 喀什市| 邵阳市| 任丘市| 三亚市| 涞源县| 泰和县| 夹江县| 临夏县| 建瓯市| 永昌县| 堆龙德庆县| 临澧县| 克什克腾旗| 九龙县| 浙江省| 吉安市| 疏勒县| 疏勒县| 长白| 拉孜县| 桃园市| 长白|