Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use of unowned inside the closure of the closure for Swift

I have a closure inside a closure, and the second closure use self, so both should have unowned self or just the second closure should have it?

dispatch_async(backgroundQueue) { [unowned self] () -> Void in
    dispatch_async(dispatch_get_main_queue(), { [unowned self] () -> Void in
        self.doSomething()
    })
}
like image 648
Daniel Gomez Rico Avatar asked Mar 17 '23 07:03

Daniel Gomez Rico


1 Answers

This is the retain graph without unowned, it doesn't have any cycles so you don't need unowned to break anything.

a -> b means a retain b

backgroundQueue -> outerBlock -> self
                       |          ^
                       V          |
      mainQueue -> innerBlock -----

A cycle is formed only when self retain any of the blocks.

Also note even backgroundQueue does retain outerBlock, the block will be released after executed, so in case self retain backgroundQueue, the retain cycle will not hold on.


This is the retain graph with unowned (your code)

a -x- b means a use b without retain it (unowned)

  backgroundQueue -> outerBlock -x- self
                           |          |
                           V          x
          mainQueue -> innerBlock -----

you can see self is not retained by anything, which means when innerBlock is executed, self may be deallocated and cause your app crash.

like image 87
Bryan Chen Avatar answered Apr 26 '23 05:04

Bryan Chen