为什么指针值在通过引用传递时会改变?

时间:2016-12-08 06:54:09

标签: ios objective-c iphone

为什么以下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
}

1 个答案:

答案 0 :(得分:3)

一个不明显的答案的好问题。

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

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的指针传递。为了支持您这样做,编译器引入了一个隐藏的临时变量并改为传递其地址。即您的代码有效地编译为:

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

因此,为什么你会看到不同的地址。