日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

Method Swizzle黑魔法,修改 ios 系统类库方法(转载)

發(fā)布時間:2023/12/1 windows 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Method Swizzle黑魔法,修改 ios 系统类库方法(转载) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一般來說,系統(tǒng)提供的方法已經(jīng)足夠開發(fā)了,但是有的時候有些需求用普通方法不好做。

如:在所有的viewcontroll 的viewwillappear:方法之前打個log

你可能會這么做:

1. 建一個uiviewcontroll 父類,重寫viewwillappear方法,調(diào)用super viewwillappear 方法之前加上log

2. 所有新建的uiviewcontroller 繼承第一步生成的

確實你是完成這樣的功能,可是你做了那么多的修改,基本每個uiviewcontroller都去修改了父類,這種方法太過于笨重了

?

本文提供了簡單地方法即可實現(xiàn)

我的理解中,object-c 的類調(diào)用方法是根據(jù)三個元素來定義的。?

1. 方法,代表類定義中一個方法類型(typedef struct objc_method *Method)

2. SEL 選擇器(typedef struct objc_selector *SEL),一個方法在運行時的名字,常見的有 [self performSelector:@selector(somemethod:) withObject:nil afterDelay:0.5]; @selector(somemethod:)作為方法的入口

3. 方法的實現(xiàn)入口(typedef id (*IMP)(id, SEL, …))

這三個元素確定了具體調(diào)用哪一個函數(shù)

?

直接看代碼

?

[objc]?view plaincopyprint?
  • #import?"UIViewController+Tracking.h"??
  • #import?<objc/runtime.h>??
  • ??
  • @implementation?UIViewController?(Tracking)??
  • ??
  • +?(void)load?{??
  • ????NSString?*className?=?NSStringFromClass(self.class);??
  • ????NSLog(@"classname?%@",?className);??
  • ????static?dispatch_once_t?onceToken;??
  • ????dispatch_once(&onceToken,?^{??
  • ????????Class?class?=?[self?class];??
  • ??????????
  • ????????//?When?swizzling?a?class?method,?use?the?following:??
  • ????????//?Class?class?=?object_getClass((id)self);??
  • ??????????
  • ????????SEL?originalSelector?=?@selector(viewWillAppear:);??
  • ????????SEL?swizzledSelector?=?@selector(xxx_viewWillAppear:);??
  • ??????????
  • ????????Method?originalMethod?=?class_getInstanceMethod(class,?originalSelector);??
  • ????????Method?swizzledMethod?=?class_getInstanceMethod(class,?swizzledSelector);??
  • ??????????
  • ????????BOOL?didAddMethod?=??
  • ????????class_addMethod(class,??
  • ????????????????????????originalSelector,??
  • ????????????????????????method_getImplementation(swizzledMethod),??
  • ????????????????????????method_getTypeEncoding(swizzledMethod));??
  • ??????????
  • ????????if?(didAddMethod)?{??
  • ????????????class_replaceMethod(class,??
  • ????????????????????????????????swizzledSelector,??
  • ????????????????????????????????method_getImplementation(originalMethod),??
  • ????????????????????????????????method_getTypeEncoding(originalMethod));??
  • ????????}?else?{??
  • ????????????method_exchangeImplementations(originalMethod,?swizzledMethod);??
  • ????????}??
  • ????});??
  • }??
  • ?

    我們category重寫了NSObject的 load 方法oc提供了objc/runtime.h類讓我們獲取這些東西,同時還提供了對類方法操作的函數(shù)

    我們想的是,直接用一個方法替換掉系統(tǒng)的方法,然后把一些自定義的動作加到方法中

    我們只想運行一次就夠了,所以使用了 dispatch_once(&onceToken, ^{ …… }
    接下來給類添加了新方法

    把新方法和系統(tǒng)方法替換

    ?

    ?

    [objc]?view plaincopyprint?
  • #pragma?mark?-?Method?Swizzling??
  • ??
  • -?(void)xxx_viewWillAppear:(BOOL)animated?{??
  • ????NSLog(@"viewWillAppear:?%@",?self);??
  • ????[self?xxx_viewWillAppear:animated];??
  • }??
  • 但是新方法實現(xiàn)的時候,調(diào)用的是 [self xxx_viewwillAppear:animated]; 可能你會疑惑

    ?

    這是因為我們在上面已經(jīng)用xxx_viewwillAppear 和 viewwillAppear 互換了。所以實際上執(zhí)行的是系統(tǒng)的viewwillAppear

    這個時候可能你又有疑問了,為什么實現(xiàn)是- (void)xxx_viewWillAppear:(BOOL)animated{} 這樣的

    這是因為 SEL swizzledSelector = @selector(xxx_viewWillAppear:); 拿的就是我們新寫的方法。

    可以結(jié)合這篇博客看,配圖很容易懂

    http://blog.csdn.net/yiyaaixuexi/article/details/9374411

    ?

    以及這篇對SEL講的比較清楚

    http://blog.csdn.net/fengsh998/article/details/8612969

    代碼下載地址

    https://github.com/holysin/Method_swizzle

    1 ?Method?nameMethod =?class_getInstanceMethod(Class class,SEL name);//得到實例方法

    參數(shù):class類名 ?name 方法名

    理解:通過類名和方法名來得到方法(c函數(shù))

    ?

    2 method_getImplementation(Method method)

    參數(shù):method 方法

    理解:通過方法來得到它的實現(xiàn)

    ?

    ?

    3 BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types)

    理解:將所給的name(方法名)的方法實現(xiàn),被imp(方法的實現(xiàn))代替

    cls:被添加方法的類

    name:可以理解為方法名,這個貌似隨便起名,

    imp:實現(xiàn)這個方法的函數(shù)?

    types:一個定義該函數(shù)返回值類型和參數(shù)類型的字符串,這個具體會在后面講

    ?

    4 class_replaceMethod(Class class,SEL ?B,?method_getImplementation(Method AMethod),?method_getTypeEncoding(Method AMethod));

    參數(shù):class :方法所屬的類 B:將被替換其實現(xiàn)的方法名 ? ?AMethod:由A生成的方法(c函數(shù))

    理解:用A的方法實現(xiàn)來代替B的方法實現(xiàn)

    5 method_exchangeImplementations(SEL A, SEL B);

    理解:交換兩個方法的實現(xiàn)

    void swizzle_method(Class class,SEL originalSelector,SEL swizzledSelector) {

    ? ? Method originalMethod = class_getInstanceMethod(class, originalSelector);//得到實例方法

    ? ? Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);

    ? ? BOOL didSwizzleMethod = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));

    ? ? if (didSwizzleMethod) {

    ? ? ? ? class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));

    ? ? } else {

    ? ? ? ? method_exchangeImplementations(originalMethod, swizzledMethod);

    ? ? }

    }

    ?

    ?

    轉(zhuǎn)載于:https://www.cnblogs.com/HughLiu/p/4648105.html

    總結(jié)

    以上是生活随笔為你收集整理的Method Swizzle黑魔法,修改 ios 系统类库方法(转载)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。