就是在不需要改变源代码逻辑的前提下,给系统的方法增加一些逻辑进去,并且这个逻辑是在整个程序的生命周期之内都能够应用.
1.方法的交换
首先在写一个 NSObject 的分类,在分类里定义一个交换方法的方法.利用 runtime 获取需要交换的方法,以及我们自己定义的去交换系统的方法的方法;得到这两个方法之后,就把方法交换.
+(void)aop_changeMethod:(SEL)oldMethod newMethod:(SEL)newMethod
{
//系统的方法
Method oldM = class_getInstanceMethod([self class], oldMethod);
//自己定义与系统方法去交换的方法
Method newM = class_getInstanceMethod([self class], newMethod);
//交换方法
method_exchangeImplementations(oldM, newM);
}
2.利用 AOP 进行权限控制
问题情况:
在一个 app 中,当用户点击的个人信息页面的时候,我们需要做一个权限控制.如果用户已经登陆,则可以顺利进入个人主页.如果没有登陆,则需要弹出一个用户登陆界面让用户登陆.登陆成功才能进到下一个页面.
解决问题:
在用户点击"我的"模块的时候,对用户是否登陆进行判断.因为用了导航控制器包装,所以用户点击进入下一页是 push的方式 .我们只要在pushViewController:animated:方法中对用户是否登陆进行判断.所以利用 aop 的思想,自己定义一个方法aop_pushViewController:animated:
交换系统的pushViewController:animated: 方法,然后在自己定义的方法中进行判断,这样就实现了不改变源代码的前提对方法进行功能增加.
代码:
/**
* 系统会在所有方法执行之前调用load方法,并且只会调用一次
* 我们可在load方法中,编写一些只需要执行一次的配置相关逻辑
*/
+(void)load
{
[UINavigationController aop_changeMethod:@selector(pushViewController:animated:) newMethod:@selector(aop_pushViewController:animated:)];
}
-(void)aop_pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
//1.在执行真正的push之前添加一些其他逻辑
NSLog(@"push 执行之前执行一些列代码");
//进行权限判断,如果已经登录的用户可以随意push任何页面
if(self.viewControllers.count > 0){
NSUserDefaults * df = [NSUserDefaults standardUserDefaults];
//取出用户信息
NSString * name = [df objectForKey:@"name"];
//哪些页面需要验证才能进入
NSString * path = [[NSBundle mainBundle] pathForResource:@"auth.plist" ofType:nil];
NSArray * tmp = [NSArray arrayWithContentsOfFile:path];
//遍历需要验证的页面,
for(NSString * className in tmp)
{
//模拟用户的验证
if([className isEqualToString:NSStringFromClass([viewController class])])
{
if(name == nil || name.length < 6)
{
//验证不通过,就进入用户登陆界面
GPLoginViewController * loginView = [[GPLoginViewController alloc] init];
UINavigationController * nav = [[UINavigationController alloc] initWithRootViewController:loginView];
[self presentViewController:nav animated:YES completion:nil];
return;
}
}
}
}//end if (self.viewControllers.count > 0)
//2.没有登录的就跳入登录页面
[self aop_pushViewController:viewController animated:animated];
//2.在原逻辑执行之后,添加一些逻辑代码
NSLog(@"push 执行之后执行一些列代码");
}
温馨提示:答案为网友推荐,仅供参考