iOS开发 内存管理strong weak 面试题

@property (nonatomic, weak) UIView *weakView;
@property (nonatomic, strong) UIView *strongView;
- (void)viewDidLoad {
  [super viewDidLoad];
  
  self.strongView = [[UIView alloc]initWithFrame:CGRectMake(25, 25, 50, 50)];
  printf("%ld",CFGetRetainCount((__bridge CFTypeRef)(self.strongView)));
  [self.view addSubview:self.strongView];
  printf("%ld",CFGetRetainCount((__bridge CFTypeRef)(self.strongView)));
  
  _strongView = [[UIView alloc]initWithFrame:CGRectMake(100, 100, 50, 50)];
  printf("%ld",CFGetRetainCount((__bridge CFTypeRef)(_strongView)));
  [self.view addSubview:self.strongView];
  printf("%ld",CFGetRetainCount((__bridge CFTypeRef)(_strongView)));
  
  UIView *selfView = [[UIView alloc]initWithFrame:CGRectMake(150, 150, 50, 50)];
  self.weakView = selfView;
  printf("%ld",CFGetRetainCount((__bridge CFTypeRef)(self.weakView)));
  [self.view addSubview:self.weakView];
  printf("%ld",CFGetRetainCount((__bridge CFTypeRef)(self.weakView)));
  
  UIView *weaksView = [[UIView alloc]initWithFrame:CGRectMake(200, 200, 50, 50)];
  printf("%ld",CFGetRetainCount((__bridge CFTypeRef)(weaksView)));
  _weakView = weaksView;
  printf("%ld",CFGetRetainCount((__bridge CFTypeRef)(_weakView)));
  [self.view addSubview:_weakView];
  printf("%ld",CFGetRetainCount((__bridge CFTypeRef)(_weakView)));
  }

请按顺序写出上述打印结果。

答案如下

self.selfStrongView = [[UIView alloc]initWithFrame:CGRectMake(25, 25, 50, 50)];
printf("self.selfStrongViewretain count = %ld\n",CFGetRetainCount((__bridge CFTypeRef)(self.selfStrongView)));

打印结果是2 因为alloc init 会生成一个强引用 引用计数+1
self.selfStringView由于走了set方法 引用计数+1

[self.view addSubview:self.selfStrongView];
printf("self.selfStrongView retain count = %ld\n",CFGetRetainCount((__bridge CFTypeRef)(self.selfStrongView)));

打印结果是3 因为addSubview 内部会把这个view添加到subviews数组里

@property(nonatomic,readonly,copy) NSArray<__kindof UIView *> *subviews;

这个数组是用copy修饰的,所以会生成一个强引用 引用计数+1

_strongView = [[UIView alloc]initWithFrame:CGRectMake(100, 100, 50, 50)];
printf("_strongView retain count = %ld\n",CFGetRetainCount((__bridge CFTypeRef)(_strongView)));

打印结果为1 因为_strongView不生成set方法 所以只有alloc init 生成的一个强引用 引用计数+1

[self.view addSubview:self.strongView];
printf("_strongView retain count = %ld\n",CFGetRetainCount((__bridge CFTypeRef)(_strongView)));

打印结果为2 原因同上一个addsubview

妈的重点来了,昨天研究这三行代码百度一晚上
知识点 : 用weak修饰的 self.语法并不会使引用计数+1

UIView *selfView = [[UIView alloc]initWithFrame:CGRectMake(150, 150, 50, 50)];
self.selfWeakView = selfView;
printf("self.selfWeakView retain count = %ld\n",CFGetRetainCount((__bridge CFTypeRef)(self.selfWeakView)));

打印结果为2 上文中我们知道 selfView的引用计数为1 为什么把值付给self.WeakView 引用计数就为2了呢
当我们把__weak修饰的变量传进NSLog方法中打印,这个方法需要持有这个变量,为了安全起见嘛,如果不强引用一下,万一还没打印的被释放了呢?
所以会对selfView调用objc_loadWeakRetained, 这时候selfView的引用计数就会+1,在NSLog结束是,会调用objc_release, 然后引用计数-1。

[self.view addSubview:self.selfWeakView];
printf("self.selfWeakView retain count = %ld\n",CFGetRetainCount((__bridge CFTypeRef)(self.selfWeakView)));

打印结果为3 因为addsubview

UIView *weaksView = [[UIView alloc]initWithFrame:CGRectMake(200, 200, 50, 50)];
printf("weakView retain count = %ld\n",CFGetRetainCount((__bridge CFTypeRef)(weaksView)));
_weakView = weaksView;
printf("_weakView retain count = %ld\n",CFGetRetainCount((__bridge CFTypeRef)(_weakView)));
[self.view addSubview:_weakView];
printf("_weakView retain count = %ld\n",CFGetRetainCount((__bridge CFTypeRef)(_weakView)));

打印结果分别为1 2 3 原因上边儿都有

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容