今是昨非

今是昨非

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

莫空面接記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;
}
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。