为什么OC中传入NSError要传指针的指针

- (id)requestWithParameter:(NSDictionary *) dic error:(NSError **) error{
//    id result = //请求
    if (result){
        return result;
    }else{
        * error = [NSError errorWithDomain:@"" code:200 userInfo:nil];
        return nil;
    }
}
  • 看到这样的代码时会不会有什么疑问?为什么传的是NSError ** ?

明确一个前提在方法中形参都是实参的值拷贝,那为什么在方法里可以访问传入的对象呢?如下代码,打印结果被修改了。

  - (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"wai%@",error.domain);
    UIView * view = [[UIView alloc] init];
    view.tag = 0;
    [self test:view];
    NSLog(@"%ld",(long)view.tag);
}
- (void)test:(UIView *)view{
    view.tag = 2;
}
-----打印结果--------
2018-08-24 18:52:06.230005+0800 测试obj[54974:2723176] 2

因为传入的参数都是指针,形如(NSString *)(NSError *)没见哪里传NSString类型的参数吧!,学过C的都清楚,指针才可以访问到真实的对象。

回到第一段代码,如果想在方法内初始化一个对象,重新给形参赋值,刚刚那种一级指针的形式可以吗?当然不可以,因为形参是实参的值拷贝,重新给形参赋值,是把新创建的对象指针赋值给形参,因为是值拷贝,并不会影响实参。所以无效。

  • 为什么传入二级指针就可以了呢?
    看第一段代码传入二级指针,我们通过 * error的形式可以访问到传入的 NSError * errro对象的值并将它的内容改变为新生成对象的指针。

总结:想改变什么值就传入什么值得指针,很明显我们想改变的是NSError *error的值,所以传入的是NSError ** error,其实这样的写法是来源于C的,因为只能有一个返回值,只能用这种方式变相返回值,学过C语言的很好理解。

你可能感兴趣的:(为什么OC中传入NSError要传指针的指针)