JS呼叫OC簡單例項-傳遞一個或者多個引數給oc方法
阿新 • • 發佈:2018-12-31
// // ViewController.m // JSCallsOC // // Created by hq on 16/4/19. // Copyright © 2016年 hanqing. All rights reserved. // #import "ViewController.h" #import "NSObject+PerformSelector.h" @interface ViewController () <UIWebViewDelegate> @property (weak, nonatomic) IBOutlet UIWebView *webView; @end @implementation ViewController -(BOOL) prefersStatusBarHidden{ return YES; } - (void)viewDidLoad { [super viewDidLoad]; NSURL *url=[[NSBundle mainBundle] URLForResource:@"index" withExtension:@"html"]; [self.webView loadRequest:[NSURLRequest requestWithURL:url]]; self.webView.delegate=self; } -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{ //js呼叫oc原理,通過特殊的url解析方法,然後呼叫oc的相應方法 NSString *urlString=request.URL.absoluteString; //我們制定了一個協議,呼叫oc的方法都以hq://開頭,後邊跟著方法名 NSString *
[email protected]"hq://"; //如果是我們自定義的協議hq://call if ([urlString hasPrefix:scheme]) { //取出scheme後邊的路徑 NSString *path=[urlString substringFromIndex:scheme.length]; //根據?區分出方法名 引數 NSArray *array=[path componentsSeparatedByString:@"?"]; NSLog(@"%@",array); NSString *methodName=array.firstObject; //將方法名中的_變成: methodName=[methodName stringByReplacingOccurrencesOfString:@"_" withString:@":"]; NSString *parameter=array.lastObject; NSArray *parameters=nil; if (array.count==2) { //繼續分解我們的變數 parameters=[parameter componentsSeparatedByString:@"&"]; } [self performSelector:NSSelectorFromString(methodName) withObjects:parameters]; return NO; } return YES; } -(void) call{ NSLog(@"沒有引數的情況--打電話給"); } -(void) call:(NSString *) number{ NSLog(@"一個引數的情況--打電話給%@",number); } -(void) call:(NSString *) number number2:(NSString *) number2{ NSLog(@"2個引數的情況--打電話給%@ %@",number,number2); } -(void) call:(NSString *) number number2:(NSString *) number2 number3:(NSString *) number3{ NSLog(@"3個引數的情況--打電話給%@ %@ %@",number,number2,number3); } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } @end
// // NSObject+PerformSelector.m // JSCallsOC // // Created by hq on 16/4/19. // Copyright © 2016年 hanqing. All rights reserved. // #import "NSObject+PerformSelector.h" @implementation NSObject (PerformSelector) - (id)performSelector:(SEL)aSelector withObjects:(NSArray *)objects{ NSMethodSignature *signature=[self.class instanceMethodSignatureForSelector:aSelector]; //如果沒有該方法 if (!signature) { @throw [NSException exceptionWithName:@"沒有該方法啊" reason:@"你確定有這個方法?" userInfo:nil]; //[NSException raise:@"出落嘍" format:@"方法找不到啊 %@",NSStringFromSelector(aSelector)]; } NSInvocation *invocation=[NSInvocation invocationWithMethodSignature:signature]; invocation.target=self; invocation.selector=aSelector; //處理引數傳多了異常 //for (int i=0; i<objects.count; i++) count得用我們方法名當中引數多個數,這樣使用者即使傳多了,也不受影響 //設定引數 //獲取方法多引數個數,注意其預設包含了self,_cmd signature.numberOfArguments所以要-2 //處理有一個活多個引數,但引數為空的問題 NSInteger count= MIN(signature.numberOfArguments-2, objects.count); for (NSInteger i=0; i<count; i++) { id object=objects[i]; [invocation setArgument:&object atIndex:2+i]; } [invocation invoke]; //獲取返回值 id returnValue=nil; if (signature.methodReturnLength) { [invocation getReturnValue:&returnValue]; } return returnValue; } @end