为什么以下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
}
答案 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 ARC和NSError and __autoreleasing。
简而言之:指向__strong
变量的指针不能作为指向__autoreleasing
的指针传递。为了支持您这样做,编译器引入了一个隐藏的临时变量并改为传递其地址。即您的代码有效地编译为:
UIView *view = [UIView new];
NSLog(@"%p",&view);
UIView __autoreleasing * compilerTemp = view;
[self test:&compilerTemp];
view = compilerTemp;
因此,为什么你会看到不同的地址。