美文网首页将来跳槽用
iOS开发 内存管理strong weak 面试题

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

作者: CurrentUserID | 来源:发表于2020-03-17 15:41 被阅读0次
    @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 原因上边儿都有

    相关文章

      网友评论

        本文标题:iOS开发 内存管理strong weak 面试题

        本文链接:https://www.haomeiwen.com/subject/hgutyhtx.html