3 回答

TA貢獻1853條經驗 獲得超18個贊
就是在不需要改變源代碼邏輯的前提下,給系統(tǒng)的方法增加一些邏輯進去,并且這個邏輯是在整個程序的生命周期之內都能夠應用.
1.方法的交換
首先在寫一個 NSObject 的分類,在分類里定義一個交換方法的方法.利用 runtime 獲取需要交換的方法,以及我們自己定義的去交換系統(tǒng)的方法的方法;得到這兩個方法之后,就把方法交換.
+(void)aop_changeMethod:(SEL)oldMethod newMethod:(SEL)newMethod
{
//系統(tǒng)的方法
Method oldM = class_getInstanceMethod([self class], oldMethod);
//自己定義與系統(tǒng)方法去交換的方法
Method newM = class_getInstanceMethod([self class], newMethod);
//交換方法
method_exchangeImplementations(oldM, newM);
}
2.利用 AOP 進行權限控制
問題情況:
在一個 app 中,當用戶點擊的個人信息頁面的時候,我們需要做一個權限控制.如果用戶已經登陸,則可以順利進入個人主頁.如果沒有登陸,則需要彈出一個用戶登陸界面讓用戶登陸.登陸成功才能進到下一個頁面.
解決問題:
在用戶點擊"我的"模塊的時候,對用戶是否登陸進行判斷.因為用了導航控制器包裝,所以用戶點擊進入下一頁是 push的方式 .我們只要在pushViewController:animated:方法中對用戶是否登陸進行判斷.所以利用 aop 的思想,自己定義一個方法aop_pushViewController:animated:
交換系統(tǒng)的pushViewController:animated: 方法,然后在自己定義的方法中進行判斷,這樣就實現了不改變源代碼的前提對方法進行功能增加.
代碼:
/**
* 系統(tǒng)會在所有方法執(zhí)行之前調用load方法,并且只會調用一次
* 我們可在load方法中,編寫一些只需要執(zhí)行一次的配置相關邏輯
*/
+(void)load
{
[UINavigationController aop_changeMethod:@selector(pushViewController:animated:) newMethod:@selector(aop_pushViewController:animated:)];
}
-(void)aop_pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
//1.在執(zhí)行真正的push之前添加一些其他邏輯
NSLog(@"push 執(zhí)行之前執(zhí)行一些列代碼");
//進行權限判斷,如果已經登錄的用戶可以隨意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.在原邏輯執(zhí)行之后,添加一些邏輯代碼
NSLog(@"push 執(zhí)行之后執(zhí)行一些列代碼");
}
- 3 回答
- 0 關注
- 1554 瀏覽
添加回答
舉報