Aop切面編程

1 什么是切面編程
2 KVO就是一個(gè)切面編程的例子
3 借鑒KVO切面編程,用自己的方法實(shí)現(xiàn)
4 代碼實(shí)現(xiàn)

切面編程概念

這種在運(yùn)行時(shí),動(dòng)態(tài)地將代碼切入到類的指定方法、指定位置上的編程思想就是面向切面的編程。

KVO切面編程實(shí)例

原理:Apple使用了isa 混寫(isa - swizzling)來(lái)實(shí)現(xiàn)。如圖


OC基礎(chǔ)-KVO

關(guān)于KVO詳細(xì)內(nèi)容請(qǐng)看我的另一篇文章http://www.itdecent.cn/p/c98c995bda08

實(shí)現(xiàn)自己的Aop

先了解一下OC消息轉(zhuǎn)發(fā)的大致原理。
1 動(dòng)態(tài)添加 resolveInstanceMethod:
2 重定向 forwardingTargetForSelector:
3 方法簽名后,調(diào)用forwardingTargetForSelector
第3步,靈活性是最大的,可以改變方法的參數(shù)內(nèi)容,個(gè)數(shù),方法名字,方法接收對(duì)象等。Aop切面編程就是用的第三個(gè)。

假設(shè)Person類,有一個(gè)實(shí)例方法sayHello(); 現(xiàn)在要求,每次調(diào)用sayHello()之前調(diào)用一段代碼Before,sayHello之后調(diào)用一段代碼after。
1 創(chuàng)建子類,避免代碼入侵。
動(dòng)態(tài)創(chuàng)建一個(gè)Person類的子類FWHook_Person ,改變person對(duì)象的isa指向FWHook_Person. 后面的步奏,都是針對(duì)FWHook_Person的
2 把sayHello的方法實(shí)現(xiàn)保存在 方法alias_sayHello中
3 替換sayHello方法實(shí)現(xiàn)為_objc_msgForward。使得person調(diào)用sayHello方法時(shí),立即觸發(fā)消息轉(zhuǎn)發(fā)機(jī)制。
4 替換forwardInvocation:為FWHook_forwardInvocation。在這里我們實(shí)現(xiàn),我們需要做的一些具體操作


Aop流程圖

當(dāng)[person sayHello]時(shí),實(shí)際調(diào)用[person _objc_msgForward], 觸發(fā)消息轉(zhuǎn)發(fā)調(diào)用 forwardInvocation的替換方法FWHook_forwardInvocation,在FWHook_forwardInvocation中依次調(diào)用before、alias_sayHello、after.

代碼實(shí)現(xiàn)

1 FWHookItem對(duì)block進(jìn)行代碼簽名

@interface FWHookItem : NSObject

@property (nonatomic, weak) id object;
@property (nonatomic, assign) SEL selector;
@property (nonatomic, assign) FWHookOption option;
@property (nonatomic, strong) id block;
@property (nonatomic, strong) NSMethodSignature *blockSignature;

+(instancetype)itemWithObject:(id)object selector:(SEL)selector option:(FWHookOption)option block:(id)block;

/*
 方法調(diào)用
 */
-(void)invokeWithParams:(NSArray*)params;

@end

2 FWHookContainer保存FWHookItem

@interface FWHookContainer : NSObject

@property(nonatomic,readonly)NSMutableArray<FWHookItem*> *beforeArray;
@property(nonatomic,readonly)NSMutableArray<FWHookItem*> *insteadArray;
@property(nonatomic,readonly)NSMutableArray<FWHookItem*> *afterArray;

-(void)addHookItem:(FWHookItem*)item;

@end

3 獲取selector參數(shù)

@interface NSInvocation (FWArguments)

- (NSArray *)getParams;

@end

4 使用

typedef void (^ParamsBlock)(NSArray *params);

@interface NSObject (FWHook)

/*
 selector : 需要監(jiān)聽的方法
 option : 決定 block 執(zhí)行時(shí)機(jī),在selector的之前,之后,替代。 
 block :執(zhí)行的代碼塊 返回的params就是,selector中的參數(shù)
 */
-(void)hookSelector:(SEL)selector withOption:(FWHookOption)option usingBlock:(ParamsBlock)block;
+(void)hookSelector:(SEL)selector withOption:(FWHookOption)option usingBlock:(ParamsBlock)block;


@end

源碼地址:https://github.com/FSilver/FWHook

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

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

  • 前言 切面編程一直是一個(gè)熱點(diǎn)的話題,這篇文章講講一個(gè)第三方aop庫(kù)在android上的應(yīng)用。 本篇文章參考以下鏈接...
    奔跑的佩恩閱讀 2,271評(píng)論 0 27
  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 2,074評(píng)論 0 9
  • 1.Aspect用戶行為統(tǒng)計(jì) 他不生成代碼,他是生產(chǎn)的搬運(yùn)工去做行為統(tǒng)計(jì) AOP切面編程 在AOP術(shù)語(yǔ)體系中,切面...
    waterge閱讀 531評(píng)論 0 0
  • AOP(Aspect-Oriented Programming)切面編程在編程中熱點(diǎn)話題之一,通過(guò)AOP可以對(duì)業(yè)務(wù)...
    FlyElephant閱讀 734評(píng)論 0 8
  • 昨晚上完老師的課,看似簡(jiǎn)單的畫作,一動(dòng)手進(jìn)入崩潰狀態(tài),臟臟的沒(méi)有輪廓的太陽(yáng)和山峰,果斷停,休息。 一早再次認(rèn)真聽課...
    KellyPENG閱讀 406評(píng)論 7 4

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