今是昨非

今是昨非

日出江花红胜火,春来江水绿如蓝

莫空面试记1

莫空面试记 1#

下午去 b 站面试,被问了一个关于内存管理的问题,问了好多,但就这个印象深刻,因为其它的不会的就算了,或者忘记的也有情可原。但这个问题答称一坨屎就太揪心了。(满满的都是泪啊)

回来的路上手机没电了,然后就想起来这个,想想,我擦,我好像知道这个是什么,再想想,我果然知道,再想想自己当时说的,我想静静
image1

看问题吧,理解就好,不要说格式错了,大概就这个

@AutoreleasePool {
  A = [[A alloc] init];
  B = [[B alloc] init];
  A.b = B;
  B.a = A;
}

然后问,这个造成循环引用了吗,哪一步造成了,能给我解释一下吗?

然后我解释成一坨屎,面试官看不下去,说怎么改,就不会循环引用了?

然后我又说一坨屎。

现在想想,我当时怎么会那么说?好像是被吓到了,面试官说的是,假设我是一个没学过 OC 的人,只会 C,然后给我解释一下;然后我就以为问的是高深的问题,然后就激动了。。。。

哎,满满的都是泪,不说了,看我回来的路上想出来的答案。

首先是造成循环引用了,这点是肯定的,然后是哪一步呢,是最后一步,如果没有最后一步,也就没有循环引用了。

  1. A = [[A alloc] init]
    这一步创建一个 A 对象,A 的引用计数为 1.
  2. B = [[B alloc] init]
    这一步创建一个 B 对象,B 的引用计数为 1.
  3. A.b = B
    这一步 A 对象持有 B 对象,B 的引用计数加 1;因为 A 持有了 B,故而,B 要想释放,需要 A 先释放持有的 B。
  4. B.a = A
    这一步 B 对象持有 A 对象,A 的引用计数加 1;同理因为 B 持有了 A,故而,A 想要释放,需要 B 线释放持有的 A。

然后这就造成循环引用了。

最后,怎么改,能让他们正常释放?更简单,因为是最后一步造成的循环引用,所以在最后一步改,就是,因为 B 持有 A 造成循环引用,那就不让 B 持有 A 啊,用__weak。。。弱引用,引用计数不会增加的。

@AutoreleasePool {
  A = [[A alloc] init];
  B = [[B alloc] init];
  A.b = B;
  __weak weakB = B;
  weakB.a = A;
}
加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。