Aspects使用

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

AOP (面向切面編程):

在軟件業(yè),AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程,通過預編譯方式和運行期動態(tài)代理實現(xiàn)程序功能的統(tǒng)一維護的一種技術。
在以下場景中,用AOP技術可以節(jié)省很多的工作量:

1.用戶通過客戶端獲取服務器端數(shù)據(jù),做權限檢查。
2.用戶和市場交互,為用戶的操作提供相應地購買參考或相關商品。
3.需要做日志記錄的操作。

安裝:

使用Aspects的項目要求是在ARC環(huán)境下,系統(tǒng)要求是iOS 7或更高,和OS X 10.7 及更高版本。滿足環(huán)境要求后,就可以使用Cocopods進行安裝了。
在Podfile下添加:

pod 'AspectsV1.4.2', '~> 1.4.2’

然后,命令行執(zhí)行:

pod install --verbose —no-repo-update

執(zhí)行成功后,重新打開我們的項目目錄下.xcworkspace文件。

主要方法:

Aspects為NSObject類提供了如下的方法:

 + (id<AspectToken>)aspect_hookSelector:(SEL)selector
                  withOptions:(AspectOptions)options
                   usingBlock:(id)block
                        error:(NSError **)error;

 - (id<AspectToken>)aspect_hookSelector:(SEL)selector
                  withOptions:(AspectOptions)options
                   usingBlock:(id)block
                        error:(NSError **)error;

這兩個方法,都可以用來修改原方法。
返回值是一個id<AspectToken>對象,可以用來注銷在方法中所做的修改:

id<AspectToken> aspect = ...;
[aspect remove];

參數(shù)里面,第一個selector用來設置需要添加功能的方法,options有如下選擇:

AspectPositionAfter   = 0,            ///在原方法調用完成以后進行調用
AspectPositionInstead = 1,            ///取代原方法                  AspectPositionBefore  = 2,            ///在原方法調用簽執(zhí)行   
AspectOptionAutomaticRemoval = 1 << 3 ///在調用了一次后清除(只能在對象方法中使用)

block是用來寫功能模塊,參數(shù)可以為空,默認的第一個參數(shù)是id<AspectInfo>類型。AspectInfo協(xié)議有如下方法:

/// 對象調用時,放回對象
- (id)instance;
/// 方法的原始實現(xiàn)
- (NSInvocation *)originalInvocation;
/// 原方法調用的參數(shù)
- (NSArray *)arguments;

最后error用于返回一個錯誤的指針。

官方的一個實用例子:

[PSPDFDrawView aspect_hookSelector:@selector(shouldProcessTouches:withEvent:) withOptions:AspectPositionInstead usingBlock:^(id<AspectInfo> info, NSSet *touches, UIEvent *event) {
    // Call original implementation.
    BOOL processTouches;
    NSInvocation *invocation = info.originalInvocation;
    [invocation invoke];
    [invocation getReturnValue:&processTouches];

    if (processTouches) {
        processTouches = pspdf_stylusShouldProcessTouches(touches, event);
        [invocation setReturnValue:&processTouches];
    }
} error:NULL];

使用:

我們創(chuàng)建好一個工程,用pods安裝好Aspects。
接著添加一個UIViewController的子類TwoViewController,從當前的ViewController點擊button可以present到TwoViewController,然后點擊TwoViewController又可以dismiss到ViewController;再給ViewController實現(xiàn)兩個touch方法,分別為點擊開始和點擊結束,用它們來改變ViewController的view屬性的一些可見的屬性,最后添加一個私有方法setupUISystem,也讓它完成一些改變view屬性的功能,在viewDidLoad調用。

好了,基本功能完成后,運行我們的工程,看是否按照預期執(zhí)行。

然后在AppDelegate的- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 生命周期方法中加入Aspects的代碼:

[UIViewController aspect_hookSelector:@selector(viewWillAppear:) withOptions:AspectPositionAfter usingBlock:^(){
    NSLog(@"view appear! -->>>>>>>>>><<<<<<<<<<<<<--");
} error:nil];

[ViewController aspect_hookSelector:@selector(touchesBegan:withEvent:) withOptions:AspectPositionInstead usingBlock:^() {
    NSLog(@"color orange!");
}error:nil];

[ViewController aspect_hookSelector:@selector(touchesEnded:withEvent:) withOptions:AspectPositionAfter usingBlock:^(){
    NSLog(@"color purle");
} error:nil];

ViewController *vc = [[ViewController alloc] init];
[vc aspect_hookSelector:@selector(setupUISystem) withOptions:AspectPositionAfter|AspectOptionAutomaticRemoval usingBlock:^(){
    NSLog(@"setupUISystem As");
} error:nil];

再運行,看看控制臺的是否有輸出,原工程的功能是否有所改變。
我們發(fā)現(xiàn):

1.在父類中的修改的方法,對子類都產(chǎn)生的作用。(1.4.2的特性)
2.Aspects的方法都按照預期執(zhí)行,修改了原功能。
3.私有方法也可以被修改。

其他:

Aspectes 會自動標記自己,所有很容易在調用棧中查看某個方法是否已經(jīng)調用:


最后附上一個統(tǒng)計功能的庫:https://github.com/orta/ARAnalytics

更多優(yōu)質文章請關注微信公眾號(iOS優(yōu)文)

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

相關閱讀更多精彩內容

  • 本章內容: 面向切面編程的基本原理 通過POJO創(chuàng)建切面 使用@AspectJ注解 為AspectJ切面注入依賴 ...
    謝隨安閱讀 3,390評論 0 9
  • 禪與 Objective-C 編程藝術 (Zen and the Art of the Objective-C C...
    GrayLand閱讀 1,758評論 1 10
  • 親愛的璐璐老師: 下午好,由于工作和家里的原因,平時很少參加幼兒園的義工活動,我感到特別的抱歉,這兩天是幼兒園...
    gracechen2020閱讀 1,910評論 0 2
  • 今天介紹的是馬賽克燈罩制作教程。 直奔主題吧。 一、材料準備。 準備的材料有馬克筆、透光的玻璃燈罩、玻璃膠、云母馬...
    深海之鯨閱讀 1,166評論 2 2
  • “哎哎,同學,掃一掃我們的二維碼吧,注冊就送小禮品!” “一共35.8,嗯嗯,可以手機支付啊,墻上就是我的二維碼,...
    Cosmono閱讀 317評論 0 0

友情鏈接更多精彩內容