1. 程式人生 > >JS呼叫OC簡單例項-傳遞一個或者多個引數給oc方法

JS呼叫OC簡單例項-傳遞一個或者多個引數給oc方法

//
//  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