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 *scheme=@"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



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值