莫空面试记1

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

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

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

1
2
3
4
5
6
@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。。。弱引用,引用计数不会增加的。

1
2
3
4
5
6
7
@AutoreleasePool {
A = [[A alloc] init];
B = [[B alloc] init];
A.b = B;
__weak weakB = B;
weakB.a = A;
}