莫空面試記 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;
}