中文字幕第五页-中文字幕第页-中文字幕韩国-中文字幕最新-国产尤物二区三区在线观看-国产尤物福利视频一区二区

iOS開發(fā):MethodSwizzling

iOS 開發(fā)之Method Swizzling

前言

如果你還不知道什么是Method Swizzling,你可以看看NSHipster 的文章 ,我簡單介紹一下,method swizzling 可以看成劫持了一個(gè)方法。

在下冶等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站制作、網(wǎng)站建設(shè) 網(wǎng)站設(shè)計(jì)制作定制網(wǎng)站建設(shè),公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),成都品牌網(wǎng)站建設(shè),成都全網(wǎng)營銷,成都外貿(mào)網(wǎng)站建設(shè),下冶網(wǎng)站建設(shè)費(fèi)用合理。


我們可以看看NSHipster 的文章中有以下代碼:

- (void)xxx_viewWillAppear:(BOOL)animated {
    [self xxx_viewWillAppear:animated];
    NSLog(@"viewWillAppear: %@", self);
}

是不是覺得遞歸無限循環(huán),事實(shí)上并不會(huì),你可以這么理解,一個(gè)具體的SEL是個(gè)名字,一個(gè)具體的IMP是個(gè)函數(shù)指針,在類里面它們是靠一個(gè)表建立聯(lián)系。


假設(shè)(純屬虛構(gòu)) UIViewController 的 @selector(viewWillAppear:) 對(duì)應(yīng)的內(nèi)部實(shí)現(xiàn)為以下

void _UIKIT_Internal_UIViewController_viewWillAppear(id vc, SEL selector, BOOL animated) {
  ...// ^_^蘋果私有代碼
}

假設(shè)UIViewController 的 @selector(xxx_viewWillAppear:) 的實(shí)現(xiàn)為以下

void my_xxx_viewWillAppear(id vc, SEL selector, BOOL animated) {
  [vc performSelector:@selector(xxx_viewWillAppear) withObject:@(animated)];  
  NSLog(@"viewWillAppear: %@", vc);
}

那么未替換方法前@selector(viewWillAppear:)對(duì)應(yīng)的指針就是&_UIKIT_Internal_UIViewController_viewWillAppear

那么未替換方法前@selector(xxx_viewWillAppear:)對(duì)應(yīng)的指針就是&my_xxx_viewWillAppear


一旦替換方法后,@selector(viewWillAppear:)對(duì)應(yīng)的指針就是&my_xxx_viewWillAppear
@selector(xxx_viewWillAppear:)對(duì)應(yīng)的指針就是&_UIKIT_Internal_UIViewController_viewWillAppear


my_xxx_viewWillAppear 中的 [vc performSelector:@selector(xxx_viewWillAppear) withObject:@(animated)];
相當(dāng)于什么,相當(dāng)于 調(diào)用@selector(xxx_viewWillAppear:)所指的函數(shù)&_UIKIT_Internal_UIViewController_viewWillAppear, 也就是相當(dāng)于調(diào)用原來的函數(shù),所以這并不是遞歸。


存在的危險(xiǎn)

  1. 有些NSObject類是類簇,替換方法要找到真正的類,如NSArray替換方法,通常用'_NSArrayM'或'_NSArrayI'
  2. 執(zhí)行順序問題,ViewController是自己寫的類,ViewController的load方法和UIViewController的category里的load方法哪個(gè)先執(zhí)行,如果是ViewController的先執(zhí)行,那么UIViewController的swizzling就對(duì)ViewController無效,如果ViewController的后執(zhí)行就一切正常,代碼如下
@implementation UIViewController (Tracking)

+ (void)load {
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    [self replaceOriginalSelector:@selector(viewWillAppear:) withNewSelector:@selector(xxx_viewWillAppear:)];
  });
}

- (void)xxx_viewWillAppear:(BOOL)animated {
  [self xxx_viewWillAppear:animated];
  NSLog(@"x_viewWillAppear: %@", self);
}
@end

@interface ViewController ()

@end

@implementation ViewController

+ (void)load {
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    [self replaceOriginalSelector:@selector(viewWillAppear:) withNewSelector:@selector(yyy_viewWillAppear:)];
  });
}

- (void)yyy_viewWillAppear:(BOOL)animated {
  [self yyy_viewWillAppear:animated];
  NSLog(@"y_viewWillAppear: %@", self);
}

@end

3.也是順序問題
以下,來自另一篇文章defagos.github.io
它是這么說的,NSObject 實(shí)現(xiàn)了 -awakeFromNib,但是它的子類UIView,孫類UILabel都沒有在本類實(shí)現(xiàn)- awakeFromNib,那么替換時(shí)如果不寫在category +(void) load方法里,那么順序也是個(gè)問題

假設(shè)我們先替換了UILabel的- awakeFromNib方法,然后再替換了UIView的- awakeFromNib,那么UILabel的- awakeFromNib方法就不會(huì)執(zhí)行UIView的- awakeFromNib方法,因?yàn)樗鼈兌际仟?dú)立替換的是NSObject方法,這篇文章defagos.github.io 提供了一個(gè)解決方案,當(dāng)本類沒有實(shí)現(xiàn)方法(如 UILabel -awakeFromNib)時(shí),首先先添加一個(gè)block方法 調(diào)用[super awakeFromNib];,我初次看到也是覺得這個(gè)方式很好,但是我發(fā)現(xiàn)兩點(diǎn)不足,

  1. 在構(gòu)建objc_super時(shí),如果父類本身沒有實(shí)現(xiàn)方法,.super_class = class_getSuperclass(clazz),這么寫好像是沒有用的,似乎super_class要填真正實(shí)現(xiàn)方法的祖先類,而不能一概的寫class_getSuperclass

    struct objc_super super = {
            .receiver = self,
            .super_class = class_getSuperclass(clazz)
        };
  2. va_list的使用
id (*objc_msgSendSuper_typed)(struct objc_super *, SEL, va_list) = (void *)&objc_msgSendSuper;

由于 va_list 變量最后是靠宏 va_arg(ap, type) 來獲取的,type又是未知的,這個(gè)函數(shù)指針的強(qiáng)制轉(zhuǎn)換轉(zhuǎn)換可能會(huì)出現(xiàn)問題


結(jié)語

可見,Swizzling正確的順序是十分重要的,(共同點(diǎn):類本身沒有真正實(shí)現(xiàn)方法)

  • 如果你的Swizzling是靜態(tài)的,那么就保證父類的Swizzling發(fā)生在子類的Swizzling前
  • 如果你的Swizzling是動(dòng)態(tài)的或者你管不好他們先后順序,那么就要用defagos的方法動(dòng)態(tài)的call objc_msgSendSuper,
  • 或許你勤快一點(diǎn)還可以直接在category里面重寫,
    - (void)awakeFromNib {
    [super awakeFromNib];
    }

新聞標(biāo)題:iOS開發(fā):MethodSwizzling
網(wǎng)頁路徑:http://m.2m8n56k.cn/article4/gdeooe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供云服務(wù)器靜態(tài)網(wǎng)站做網(wǎng)站網(wǎng)站收錄網(wǎng)站營銷企業(yè)網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:[email protected]。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設(shè)
主站蜘蛛池模板: 国产精品自拍亚洲 | 国产香蕉成人综合精品视频 | 一级视频网站 | 国产精品日韩欧美一区二区三区 | 成人a免费α片在线视频网站 | 在线观看精品自拍视频 | 欧美性狂猛bbbbbbxxxxxx | 国产精品不卡无毒在线观看 | 日韩欧美一区二区三区不卡视频 | 一级毛片美国aaj毛片 | 性刺激欧美三级在线现看中文 | 欧美巨大精品欧美一区二区 | 她也啪在线视频 | 国产成人91一区二区三区 | 国产成人啪精品视频免费网 | 毛片在线播放网址 | 清纯偷拍精品视频在线观看 | 国产精品久久一区二区三区 | 国产在亚洲线视频观看 | 国产一二三区在线 | 米奇精品一区二区三区 | 久久狠狠色狠狠色综合 | 乱码一区 | 亚洲日本一区二区三区 | 久久中文字幕免费视频 | 国产精品1区 2区 3区 | 中文字幕亚洲不卡在线亚瑟 | 日韩天天摸天天澡天天爽视频 | 国产美女做爰免费视频网址 | 国产精品亚洲精品影院 | 91chinesevideo在线观看 | 亚洲特级黄色片 | 欧美在线播放视频 | 国产91精品一区二区麻豆亚洲 | 女人张开腿让男人操 | 国产视频精品久久 | 亚洲精品一二三区-久久 | 最新怡红院全部视频在线 | 亚洲黄色小视频 | 日日a.v拍夜夜添久久免费 | 日本一级特黄大一片免 |