【问题标题】:Why the pointer value is changed when passing by reference?为什么通过引用传递时指针值会改变?
【发布时间】:2016-12-08 06:54:08
【问题描述】:

为什么下面的 NSLog 结果不一样?

UIView *view = [UIView new];
NSLog(@"%p",&view); //0x7fff59c86848
[self test:&view];

-(void)test:(UIView **)view{
   NSLog(@"%p",view); // 0x7fff59c86840
}

虽然以下 NSLog 结果相同?

 NSInteger j = 1;
 NSLog(@"%p", &j);//0x7fff5edc7ff8
 [self test1:&j];

- (void)test1:(NSInteger *)j{
   NSLog(@"%p", j);//0x7fff5edc7ff8
}

【问题讨论】:

    标签: ios objective-c iphone


    【解决方案1】:

    好问题,答案不明显。

    这完全与与变量相关的所有权限定符有关。当你声明:

    NSView *view;
    

    这是以下的简写:

    NSView __strong * view;
    

    即引用由变量view 强烈持有。

    但是当你声明时:

    -(void)test:(UIView **)view
    

    这是以下的简写:

    -(void)test:(UIView * __autoreleasing *)view
    

    这里 view 是指向变量的类型指针 __autoreleasing 指向 UIView 的指针。

    __strong__autoreleasing 之间存在差异的原因在于 Apple 术语的回写调用,并在 Variable Qualifiers in Apple's "Transitioning to ARC Release Notes"Ownership qualification in CLANG Documentation: Automatic Reference Counting 中进行了解释。还解释了SO问题Handling Pointer-to-Pointer Ownership Issues in ARCNSError and __autoreleasing

    简而言之:指向__strong 变量的指针不能作为指向__autoreleasing 变量的指针传递。为了支持你这样做,编译器引入了一个隐藏的临时变量并传递它的地址。 IE。您的代码被有效地编译为:

    UIView *view = [UIView new];
    NSLog(@"%p",&view);
    UIView __autoreleasing * compilerTemp = view;
    [self test:&compilerTemp];
    view = compilerTemp;
    

    因此您看到的地址不同。

    【讨论】:

    • 谢谢,您的回答非常准确。逆向工程结果如您所说。并且地址在 MRC 中是一样的。
    猜你喜欢
    • 1970-01-01
    • 2018-08-19
    • 2020-12-17
    • 1970-01-01
    • 1970-01-01
    • 2014-11-15
    • 2014-07-27
    • 2023-03-03
    相关资源
    最近更新 更多