莫空面试记 1#
下午去 b 站面试,被问了一个关于内存管理的问题,问了好多,但就这个印象深刻,因为其它的不会的就算了,或者忘记的也有情可原。但这个问题答称一坨屎就太揪心了。(满满的都是泪啊)
回来的路上手机没电了,然后就想起来这个,想想,我擦,我好像知道这个是什么,再想想,我果然知道,再想想自己当时说的,我想静静
看问题吧,理解就好,不要说格式错了,大概就这个
@AutoreleasePool {
A = [[A alloc] init];
B = [[B alloc] init];
A.b = B;
B.a = A;
}
然后问,这个造成循环引用了吗,哪一步造成了,能给我解释一下吗?
然后我解释成一坨屎,面试官看不下去,说怎么改,就不会循环引用了?
然后我又说一坨屎。
现在想想,我当时怎么会那么说?好像是被吓到了,面试官说的是,假设我是一个没学过 OC 的人,只会 C,然后给我解释一下;然后我就以为问的是高深的问题,然后就激动了。。。。
哎,满满的都是泪,不说了,看我回来的路上想出来的答案。
首先是造成循环引用了,这点是肯定的,然后是哪一步呢,是最后一步,如果没有最后一步,也就没有循环引用了。
- A = [[A alloc] init]
这一步创建一个 A 对象,A 的引用计数为 1. - B = [[B alloc] init]
这一步创建一个 B 对象,B 的引用计数为 1. - A.b = B
这一步 A 对象持有 B 对象,B 的引用计数加 1;因为 A 持有了 B,故而,B 要想释放,需要 A 先释放持有的 B。 - 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;
}