Aspects使用

作者: AirChen | 来源:发表于2016-12-19 18:53 被阅读1434次

Aspects是一个简洁高效的用于使iOS支持AOP面向切面编程的库.它可以帮助你在不改变一个类或类实例的代码的前提下,有效更改类的行为.

AOP (面向切面编程):

在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
在以下场景中,用AOP技术可以节省很多的工作量:

1.用户通过客户端获取服务器端数据,做权限检查。
2.用户和市场交互,为用户的操作提供相应地购买参考或相关商品。
3.需要做日志记录的操作。

安装:

使用Aspects的项目要求是在RAC环境下,系统要求是iOS 7或更高,和OS X 10.7 及更高版本。满足环境要求后,就可以使用Cocopods进行安装了。
在Podfile下添加:

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

然后,命令行执行:

pod install --verbose —no-repo-update

执行成功后,重新打开我们的项目目录下.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];

参数里面,第一个selector用来设置需要添加功能的方法,options有如下选择:

AspectPositionAfter   = 0,            ///在原方法调用完成以后进行调用
AspectPositionInstead = 1,            ///取代原方法                  AspectPositionBefore  = 2,            ///在原方法调用签执行   
AspectOptionAutomaticRemoval = 1 << 3 ///在调用了一次后清除(只能在对象方法中使用)

block是用来写功能模块,参数可以为空,默认的第一个参数是id<AspectInfo>类型。AspectInfo协议有如下方法:

/// 对象调用时,放回对象
- (id)instance;
/// 方法的原始实现
- (NSInvocation *)originalInvocation;
/// 原方法调用的参数
- (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];

使用:

我们创建好一个工程,用pods安装好Aspects。
接着添加一个UIViewController的子类TwoViewController,从当前的ViewController点击button可以present到TwoViewController,然后点击TwoViewController又可以dismiss到ViewController;再给ViewController实现两个touch方法,分别为点击开始和点击结束,用它们来改变ViewController的view属性的一些可见的属性,最后添加一个私有方法setupUISystem,也让它完成一些改变view属性的功能,在viewDidLoad调用。

好了,基本功能完成后,运行我们的工程,看是否按照预期执行。

然后在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];

再运行,看看控制台的是否有输出,原工程的功能是否有所改变。
我们发现:

1.在父类中的修改的方法,对子类都产生的作用。(1.4.2的特性)
2.Aspects的方法都按照预期执行,修改了原功能。
3.私有方法也可以被修改。

其他:

Aspectes 会自动标记自己,所有很容易在调用栈中查看某个方法是否已经调用:


最后附上一个统计功能的库:https://github.com/orta/ARAnalytics

更多优质文章请关注微信公众号(iOS优文)

相关文章

  • AOP埋点

    AOP的框架使用的是 Aspects[https://github.com/steipete/Aspects],使...

  • iOS-Aspect简单使用(AOP)

    使用cocoapods将Aspects添加到project中。 1.主要使用Aspects 中以下两个方法对pro...

  • Aspects使用

    Aspects是一个简洁高效的用于使iOS支持AOP面向切面编程的库.它可以帮助你在不改变一个类或类实例的代码的前...

  • 使用Aspects遇到exc_bad_access的问题

    项目中需要对某些事件进行统计,我直接使用了Aspects的;问题发送在当Aspects对控制器的viewDidDi...

  • Aspects原理详解

    Aspects是什么 Aspects[https://github.com/steipete/Aspects]是一...

  • iOS开发之优秀三方库

    切面埋点 Aspects Aspects 广告页面库 XHLaunchAd

  • iOS - Aspects实现原理解析

    两个问题 Aspects如何hook实例方法? Aspects如何hook类的实例方法? 注:Aspects目前不...

  • Aspects原理和使用

    前言 在读这篇文章之前,需要对Runtime消息发送、消息转发有一定的了解。Runtime系列Objective-...

  • IOS框架使用:Aspects

    原创:知识进阶型文章创作不易,请珍惜,之后会持续更新,不断完善个人比较喜欢做笔记和写总结,毕竟好记性不如烂笔头哈哈...

  • iOS Aspects 使用-坑点

    Aspects https://github.com/steipete/Aspects[https://githu...

网友评论

    本文标题:Aspects使用

    本文链接:https://www.haomeiwen.com/subject/igitvttx.html