iOS Aspects --- AOP(面向切面編程)

人生如夢,一樽還酹江月。

前言

移動端開發(fā)常態(tài),忙一陣閑一陣。這不,又到了閑的階段了,趁還有點閑的時間(產(chǎn)品悄悄對我說,今天下個項目原型通過了,下周開始加班)就趕緊整合之前用到的知識點,一是方便自己以后查閱,二是也方便有需要的iOSer。

Aspects 簡介

Aspects是一個簡潔高效的用于使iOS支持AOP面向切面編程的庫,它可以幫助你在不改變一個類或類實例的代碼的前提下,有效更改類的行為。

使用需求

  • ARC
  • 使用iOS 7+和OS X 10.7或更高版本測試方面。

使用場景

  • 統(tǒng)一處理邏輯。
  • 在不改變源碼的情況下,插入代碼(如無侵染更改第三方庫代碼,干一些壞壞的事情)

有些小伙伴一看這個庫,發(fā)現(xiàn)最近更新也是3年前,擔(dān)心庫有問題。聽一大牛說,這個庫偏底層,只要Apple底層框架不變,那這個庫就很穩(wěn)定。

Aspects github 地址

Aspects 使用

pod search AspectsV1.4.2

該庫是輕量級的,接口簡單,只有2個方法:

/*
 *    selector: 要hook的目標(biāo)方法 
 *    AspectOptions: 枚舉 
             AspectPositionAfter  //目標(biāo)方法調(diào)用之后走block
             AspectPositionInstead //替換目標(biāo)方法
             AspectPositionBefore //目標(biāo)方法之前
             AspectOptionAutomaticRemoval //只實現(xiàn)一次
      block:結(jié)合后面的demo看
      error:拋出錯誤
 *
 *
 *
 */
+ (id<AspectToken>)aspect_hookSelector:(SEL)selector
                           withOptions:(AspectOptions)options
                            usingBlock:(id)block
                                 error:(NSError **)error;

/// Adds a block of code before/instead/after the current `selector` for a specific instance.
- (id<AspectToken>)aspect_hookSelector:(SEL)selector
                           withOptions:(AspectOptions)options
                            usingBlock:(id)block
                                 error:(NSError **)error;

注意:上面2個方法只能hook實例(-)方法,對類(+)方法無效

官方demo

[UIViewController aspect_hookSelector:@selector(viewWillAppear:) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> aspectInfo, BOOL animated) {
    NSLog(@"View Controller %@ will appear animated: %tu", aspectInfo.instance, animated);
} error:NULL];

demo上會發(fā)現(xiàn)有個AspectInfo,看源碼:

@protocol AspectInfo <NSObject>

//返回調(diào)用者實例
- (id)instance;
//方法簽名信息
- (NSInvocation *)originalInvocation;
//原方法調(diào)用的參數(shù)
- (NSArray *)arguments;

@end

目前用到:在appDelegate

// 勾取 UIViewController 類所有實例的viewWillAppear: 方法
    [UIViewController aspect_hookSelector:@selector(viewWillAppear:) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> info){
        UIViewController *tempVC = (UIViewController *)info.instance;
        NSLog(@">>>%@ viewWillAppear",[tempVC class]);
    } error:nil];
    
    [UIControl aspect_hookSelector:@selector(sendAction:to:forEvent:) withOptions:AspectPositionBefore usingBlock:^(id<AspectInfo> info){
        UIControl *control = (UIControl *)info.instance;
        if ([control isKindOfClass:[UIButton class]]) {
            UIButton *btn = (UIButton *)control;
            NSLog(@">>>%@",btn.titleLabel.text);
        }
    } error:nil];

實現(xiàn)效果,對所有ViewController的生命周期和button的點擊事件進行統(tǒng)計。
由于時間問題,對源碼不再詳細的闡述,源碼用的核心知識點有:

  • 消息轉(zhuǎn)發(fā)
  • runtime
  • 自旋鎖 (OSSpinLockLock)
  • block的底層結(jié)構(gòu)

后記

目前只是簡單的使用,以后有時間了就把源碼解析補出來。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Oracle筆記系列這幾篇是來自一位老師的筆記,分享給大家放在簡書上,主要方便自己時常復(fù)習(xí),還有學(xué)習(xí)Oracle的...
    panda_Hi閱讀 986評論 0 0
  • #五五開封號# 一早醒來,手機就被五五開刷屏了,網(wǎng)友評論也是一波的隨風(fēng)倒,頗有一股子“君子報仇十年不晚”的豪氣,很...
    木阿桑閱讀 347評論 1 0
  • 終于,在廣州一個寒冷的冬夜里,我讀完了《最好的告別》(Being Mortal)這本書,一本由美國醫(yī)生阿圖·葛文德...
    筱慕雪閱讀 15,104評論 2 2
  • 我很荒唐 這個世界沒有上帝 世界也只是名詞 我很荒唐 沒有人規(guī)定荒唐的人不能做什么 人也是個名詞 我很荒唐 荒唐是...
    盲碼閱讀 201評論 0 1

友情鏈接更多精彩內(nèi)容