简体   繁体   中英

Swift, how much of “self” do closures capture?

I am confused by this situation:

  1. Class A hands an escaping closure Z to some global queue.

  2. In closure Z, we call funcs in class A, and class B who is only referenced from class A.

  3. Just before closure Z calls functions from class B, class B gets cleaned out.

  4. What does class B mean to closure Z at this point? Is it still the old B at time of capture or the new nil? (Assuming B was a delegate)

==

Another follow up question would be, if the funcs of class B called by closure Z reference a bunch more things in class B, how is the "self" of B captured, is it strong or weak?

My confusion comes because in closure Z, i can specify [weak self], but I cannot do that for the functions I want to call in class B.

and class B who is only referenced from class A.

This means either two things:

  1. B instance is a strong property, and will not be released at least until A instance gets released, and A instance will not get released until the end of the closure.

  2. B instance is a weak property, and might get released at any time ( A instance has nothing to say in this case). But at the same time it means B instance has to be optional therefore the compiler will force you to properly handle the scenario where it is deallocated (of course you can force unwrap it, but then it's your problem).

class B who is only referenced from class A.

I assume you mean something like this in A :

var objB: B?

Just before closure Z calls functions from class B, class B gets cleaned out.

Well, there is only one way to clean out B :

objB = nil

Now when you call B's methods in the closure, you will get an "unexpectedly found nil while unwrapping an optional value".

This is because you only captured self , which is A ,in the closure. You did not capture B at all. The instance of B is retained by the strong reference from A . Basically, B is not captured by the closure.

My confusion comes because in closure Z, i can specify [weak self], but I cannot do that for the functions I want to call in class B.

Well, you can capture B though. Just like this:

[b = self.objB] in ...

You can also make it weak:

[weak b = self.objB] in ...

This way you can also capture B in the closure.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM