最近在重温iOS与OSX多线程和内存管理这本书,发现平常没注意到的问题。
在ARC下 如何使用二级指针
NSObject *obj = [[NSObject alloc] init];
NSLog(@"getNewObject Before %p",obj);
[self getNewObjcet: &obj];
NSLog(@"getNewObject after %p",obj);
-(void)getNewObjcet:(NSObject **) obj{
NSLog(@"getNewObject Before %p",*obj);
*obj = [[NSObject alloc]init];
NSLog(@"getNewObject after %p",*obj);
}
打印结果:
在OC里通常命名getXXX传入 返回值以指针形式返回
按道理getNewObjcet 中
*object 就是外面的obj
object 就是外面的&obj
NSObject *obj = [[NSObject alloc]init];
NSLog(@"\ngetNewObject Before %p",obj);
NSLog(@"\ngetNewObject &obj %p",&obj);
[self getNewObjcet:&obj];
NSLog(@"\ngetNewObject after %p",obj);
-(void)getNewObjcet:(NSObject**)object{
NSLog(@"\nIN getNewObject object ==? &obj %p",object);
NSLog(@"\nIN getNewObject Before %p",*object);
*object = [[NSObject alloc]init];
NSLog(@"\nIN getNewObject after %p",*object);
}
但打印getNewObjcet中的object 一看究竟
内存地址对不上呀 为什么会这样 他们不是一个东西嘛?
对的他们不是同一个东西
其实调用 [self getNewObjcet: (NSObject *__autoreleasing *)];代码补全时候告诉了我们
非显式使用__autoreleasing id *obj 其实就是id __autoreleasing *obj
对象的指针就是 NSObject **obj = = >> NSObject *__autoreleasing *obj
默认的
-(void)getNewObjcet:(NSObject **)object ==>> -(void)getNewObjcet:(NSObject *__autoreleasing *)object
由于上面的 NSObject *obj = [[NSObject alloc]init]; 默认修饰符 __strong
NSObject *obj = [[NSObject alloc]init];
NSObject *__autoreleasing * objPtr = &obj;
这样是不可行的 Initializing 'NSObject *__autoreleasing *' with an expression of type 'NSObject *__strong *' changes retain/release properties of pointer
所以其实在ARC下编译器 帮我们做了这件事情
NSObject __autoreleasing *temp = obj;
NSObject *__autoreleasing *tempPtr = &temp;
[self getNewObjcet: tempPtr];
综上所述 他把我们的temp 偷偷的藏起来了。