今是昨非

今是昨非

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

Interview Notes 1

Mo Kong Interview Notes 1#

I went to B station for an interview in the afternoon and was asked a question about memory management. They asked a lot of questions, but this one left a deep impression on me, because I can let go of the ones I don't know or have forgotten. But it was really painful to answer this question so poorly. (Tears were streaming down my face)

On the way back, my phone ran out of battery, and then I remembered this. I thought to myself, "Oh my, I think I know what this is." And then I thought some more, and I really did know. And then I thought about what I said at that time, and I just wanted to be alone.
image1

Take a look at the question, just understand it, don't worry about the formatting, it's probably like this:

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

Then they asked, does this cause a retain cycle? Which step causes it? Can you explain it to me?

And then I explained it poorly, the interviewer couldn't bear to watch and asked how to fix it so that there won't be a retain cycle?

And then I said something even worse.

Now that I think about it, why did I say that at the time? It seems like I was scared. The interviewer said, imagine I'm someone who hasn't learned Objective-C and only knows C, and explain it to me. And then I thought it was a complicated question, and got excited...

Sigh, tears were streaming down my face, I won't say anymore, let's take a look at the answer I came up with on the way back.

First, a retain cycle is definitely caused, and then which step is it? It's the last step, if there's no last step, there won't be a retain cycle.

  1. A = [[A alloc] init]
    This step creates an A object, with a retain count of 1.
  2. B = [[B alloc] init]
    This step creates a B object, with a retain count of 1.
  3. A.b = B
    This step makes A hold a reference to B, increasing B's retain count by 1; because A holds B, in order for B to be released, A needs to release the reference it holds to B.
  4. B.a = A
    This step makes B hold a reference to A, increasing A's retain count by 1; similarly, because B holds A, in order for A to be released, B needs to release the reference it holds to A.

And this causes a retain cycle.

Finally, how to fix it and make them release properly? It's actually quite simple, because the retain cycle is caused by the last step, we can just modify the last step. Since B holds A and causes the retain cycle, we can simply not let B hold A, by using __weak... a weak reference, which doesn't increase the retain count.

@AutoreleasePool {
  A = [[A alloc] init];
  B = [[B alloc] init];
  A.b = B;
  __weak weakB = B;
  weakB.a = A;
}
Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.