Aspects框架

Aspects简介:

Aspect是一个基于method swizzing的iOS函数替换的轻量级的第三方库(不足千行代码),有关iOS运行时的相关知识,移步 runtime从入门到精通,他可以很好的实现勾取一个类或者一个对象的某个方法。

Aspects 的 github地址

面向切面(AOP)编程

面向切面编程就是通过预编译和运行期动态代理实现给程序动态统一添加功能的一种技术,使用Aspects框架就是 AOP 编程。

Aspects框架的对外的两个重要接口声明:

/// Adds a block of code before/instead/after the current `selector` for a specific class.
///
/// @param block Aspects replicates the type signature of the method being hooked.
/// The first parameter will be `id<AspectInfo>`, followed by all parameters of the method.
/// These parameters are optional and will be filled to match the block signature.
/// You can even use an empty block, or one that simple gets `id<AspectInfo>`.
///
/// @note Hooking static methods is not supported.
/// @return A token which allows to later deregister the aspect.
+ (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;

以第二个接口为例进行说明:

/**
 *   勾取某一对象的某一方法
 *   selector : 指定对象的方法
 *   options :枚举类型
 *   block :执行的自定义方法。在这个block里面添加我们要执行的代码。
 **/
- (id<AspectToken>)aspect_hookSelector:(SEL)selector
                           withOptions:(AspectOptions)options
                            usingBlock:(id)block
                                 error:(NSError **)error;

AspectOptions 枚举定义如下,我们一般使用 AspectPositionAfter。AspectPositionAfter 表示 selector 方法执行后会触发block中的代码,AspectPositionBefore 表示方法执行前先触发block中的代码,AspectPositionInstead 表示直接替换原方法。

typedef NS_OPTIONS(NSUInteger, AspectOptions) {
    AspectPositionAfter   = 0,            /// Called after the original implementation (default)
    AspectPositionInstead = 1,            /// Will replace the original implementation.
    AspectPositionBefore  = 2,            /// Called before the original implementation.

    AspectOptionAutomaticRemoval = 1 << 3 /// Will remove the hook after the first execution.
};

Aspects框架的使用

使用场景举例

对用户的页面轨迹进行统计,也即用户每次进入到一个控制器调用 viewWillAppear 函数时进行相应的处理(例如友盟统计)

代码实现

使用cocoapods将Aspects添加到project中。

target 'Project' do
    use_frameworks!
    pod 'Aspects', '~> 1.4.1'
end

创建一个工具类,导入头文件:

#import <Aspects/Aspects.h>

实现代码:

+ (void)Aspect {

   /**
   *  事件拦截
   *  拦截UIViewController的viewWillAppear方法
   */
   [UIViewController aspect_hookSelector:@selector(viewWillAppear) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> aspectInfo) {
   //NSLog(@"viewWillAppear调用了 --- %@ --- %@ --- %@",aspectInfo.instance,aspectInfo.arguments, aspectInfo.originalInvocation);
   NSLog(@"%@ 对象的viewWillAppear调用了",aspectInfo.instance);

   /**
    *  添加我们要执行的代码
    */

   } error:NULL];

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值