Upgrade to Pro — share decks privately, control downloads, hide ads and more …

君の参照は。〜classとfunctionと循環参照の話〜

704056da9a4c4e075ad14479beaebab7?s=47 takasek
September 19, 2016

 君の参照は。〜classとfunctionと循環参照の話〜

2016/9/16 歌舞伎座.tech #11 (http://kbkz.connpass.com/event/37480/) での発表「君の参照は。」の資料です。
発表中に使用した循環参照検証用プロジェクトもあわせてお試し下さい。
https://github.com/takasek/RecursiveReferenceSample

704056da9a4c4e075ad14479beaebab7?s=128

takasek

September 19, 2016
Tweet

Transcript

  1. takasek؂ಜ ࠷৽࡞ ɹ܅ ͷ ࢀ র ͸ ɻ 2016/9/16 Վ෣ب࠲.tech

    #11 1
  2. ·ͩdeinitͨ͜͠ͱͷͳ͍܅ (class) Λɺ ڧࢀর͍ͯ͠Δɻ 2

  3. 3

  4. 4

  5. ɹ࿩͕௕͍ͷͰɺ ɹ·ͣ͸݁࿦ɻ 5

  6. classͷ Πϯελϯεϝιου͸ self΁ͷڧࢀরΛ ͍࣋ͬͯΔͷͰ ؾΛ͚ͭΖɻ 6

  7. Ͱ͸ ຊ୊ελʔτ! 7

  8. ϘλϯΛͻͱ͚ͭͩ࣋ͭ UIViewαϒΫϥεͷίϯϙʔωϯτΛ࡞ͬͨͱ͠·͢ɻ final class MyComponent: UIView { @IBOutlet private var

    button: UIButton! //Button͕ԡ͞ΕͨΒɺcallbackΛ࣮ߦ var callback: (() -> Void)? @IBAction func didButtonPush() { callback?() } } 8
  9. ͜ͷίϯϙʔωϯτʹcallbackͱͯؔ͠਺Λ౉ͯ͠ɺ ViewControllerͰॲཧͰ͖ΔΑ͏ʹ͠·͢ɻ final class ViewController: UIViewController { @IBOutlet private var

    component: MyComponent! override func viewDidLoad() { super.viewDidLoad() component.callback = { ͳΜ͔ॲཧΛ͢Δ() } } deinit { print("deinit") } } 9
  10. final class ViewController: UIViewController { @IBOutlet private var component: MyComponent!

    override func viewDidLoad() { super.viewDidLoad() component.callback = { ͳΜ͔௕͍ॲཧ() if something.isͳΜͨΒ { ଞͷ௕͍ॲཧ() } else { something.΄͛΄͛() } } } deinit { print("deinit") } } ! callbackͷத਎͕๲ΒΜͰ͖ͨ 10
  11. final class ViewController: UIViewController { @IBOutlet private var component: MyComponent!

    override func viewDidLoad() { super.viewDidLoad() component.callback = { self.doHogehoge() } } private func doHogehoge() { ... } deinit { print("deinit") } } ☺ ϝιουʹ੾Γग़ͯ͠ɺ͖ͬ͢Γ 11
  12. !…଴ͯΑʁ component.callback = { self.doHogehoge() } !Ϋϩʔδϟͷதʹself͕ొ৔͢Δ৔߹͸ɺ॥؀ ࢀরʹؾΛ͚ͭΔඞཁ͕͋ΔΜͩͬͨͳ…ʁ 12

  13. !॥؀ࢀর self ➡ self.component self.component ➡ self.component.callback self.component.callback ➡ self

    ɹ let closure = { //Ϋϩʔδϟ͕selfΛڧࢀরͰΩϟϓνϟ͍ͯ͠Δ self.ʙʙʙ } 13
  14. ! ͳΒ͜ΕͰ… component.callback = { [weak self] in self?.doHogehoge() }

    ! ऑࢀরʹͯ͠ɺ᠘Λ՚ྷʹճආʂ 14
  15. final class ViewController: UIViewController { @IBOutlet private var component: MyComponent!

    override func viewDidLoad() { super.viewDidLoad() component.callback = { [weak self] in self?.doHogehoge() } } private func doHogehoge() { // ... } deinit { print("deinit") } } ɹ ☺ ͖ͬ͢ΓΞήΠϯ 15
  16. ... { ... component.callback = { [weak self] in self?.doHogehoge()

    } } private func doHogehoge() { // ... } ! ͍΍ɺͰ΋଴ͯΑ… ɹ ͜ͷΫϩʔδϟɺແବ͡Όͳ͍͔ʁ 16
  17. ! ͦ͏ͩɺSwiftͰ͸ ɹ ؔ਺΋ୈҰڃΦϒδΣΫτͩ final class MyComponent: UIView { var

    callback: (() -> Void)? } final class ViewController: UIViewController { private func doHogehoge() { } ! ͦͯ͠ϝιου doHogehoge ΋ ɹ ϓϩύςΟ callback ͱಉ͡ ()->Void ܕ ɹ ͱ͍͏͜ͱ͸… 17
  18. ɹ ɹ component.callback = doHogehoge ɹ ! …͜Εͩʂ 18

  19. final class ViewController: UIViewController { @IBOutlet private var component: MyComponent!

    override func viewDidLoad() { super.viewDidLoad() component.callback = doHogehoge // ! } private func doHogehoge() { // ... } deinit { print("deinit") } } ! ܕ͸߹ͬͯΔʂ ɹ ͜ͷॻ͖ํ…coool͡Όͳ͍!? ɹ doHogehogeͷதͰ͸self࢖ͬͯͳ͍͠ʂ 19
  20. ͱࢥͬͨΒɺҧͬͨ 20

  21. deinit { print("deinit") } ! deinitɺݺ͹Εͯͳ͍ΜͰ͚͢Ͳʂʂ 21

  22. !॥؀ࢀরͷग़དྷ্͕Γ self ➡ self.component self.component ➡ self.doHogehogeϝιου self.doHogehogeϝιου ➡ self

    ɹɹɹɹɹɹɹɹɹɹɹɹɹ "!? 22
  23. ϝιου͸҉໧తʹ self΁ͷڧࢀরΛ ͍࣋ͬͯΔ 23

  24. ϝιου͕functionܕ ͔ͩΒͱݴͬͯɺ ܰ཰ʹଞͷܕʹ౉ͯ͠ ॴ༗ͤͯ͞͸͍͚ͳ͍ 24

  25. ͜͜Ͱ ಥવͷΫΠζʂ 25

  26. ͜Ε͔Βɺ͍Ζ͍ΖͳfunctionܕΛɺ͍Ζ͍ΖͳܗͰ component.callback ϓϩύςΟʹ౉͠·͢ɻ ָ͠Έํ ·ͣɺίʔυΛఏࣔ͠·͢ɻ ఏࣔ͞Εͨίʔυ͕॥؀ࢀরΛى͔͜͢ɺͬ͘͡Γߟ͑ ͯΈ·͠ΐ͏ɻ ϖʔδΛΊ͘Ε͹౴͑߹Θͤɻ ݁Ռʢ ݈શ!

    or ॥؀ࢀর" ʣ͕෼͔Γ·͢ɻ ΫΠζؾ෼Ͱ௅ઓͯ͠Έ͍ͯͩ͘͞Ͷɻ 26
  27. ݕূ༻ϓϩδΣΫτ https://github.com/ takasek/ RecursiveReferenceSample projectΛϏϧυͯ͠ɺࣗ෼Ͱ ಈ͔ͯ͠Έͯ΋ָ͍͔͠΋͠ Ε·ͤΜɻ 27

  28. here we go! 28

  29. ϝιου final class ViewController: UIViewController { private func doHogeMethod() {

    print("method") } func configureButtonAction() { component.callback = doHogeMethod } } ݁Ռ͸… 29
  30. ϝιου final class ViewController: UIViewController { private func doHogeMethod() {

    print("method") } func configureButtonAction() { component.callback = doHogeMethod } } ݁Ռ: ॥؀ࢀর! 30
  31. ϝιου([unowned self]ͳΫϩʔδϟ͔ΒݺͿ) final class ViewController: UIViewController { private func doHogeMethod()

    { print("method") } func configureButtonAction() { component.callback = { [unowned self] in self.doHogeMethod() } } } ݁Ռ͸… 31
  32. ϝιου([unowned self]ͳΫϩʔδϟ͔ΒݺͿ) final class ViewController: UIViewController { private func doHogeMethod()

    { print("method") } func configureButtonAction() { component.callback = { [unowned self] in self.doHogeMethod() } } } ݁Ռ: ݈શ! 32
  33. functionܕϓϩύςΟ final class ViewController: UIViewController { let functionTypeProperty = {

    print("function-type property") } func configureButtonAction() { component.callback = functionTypeProperty } } ݁Ռ͸… 33
  34. functionܕϓϩύςΟ final class ViewController: UIViewController { let functionTypeProperty = {

    print("function-type property") } func configureButtonAction() { component.callback = functionTypeProperty } } ݁Ռ: ݈શ! 34
  35. functionܕϓϩύςΟ(தͰselfΛ࢖͏) final class ViewController: UIViewController { let functionTypePropertyUsingSelf = {

    print("function-type property using self", self) } func configureButtonAction() { component.callback = functionTypePropertyUsingSelf } } ݁Ռ͸… 35
  36. functionܕϓϩύςΟ(தͰselfΛ࢖͏) final class ViewController: UIViewController { let functionTypePropertyUsingSelf = {

    print("function-type property using self", self) } func configureButtonAction() { component.callback = functionTypePropertyUsingSelf } } ݁Ռ: ݈શ! 36
  37. let functionTypePropertyUsingSelf = { print("function-type property using self", self) }

    func configureButtonAction() { component.callback = functionTypePropertyUsingSelf } ɹ !଴ͬͯ଴ͬͯɺ͜ΕϚδͰ॥؀ࢀরى͖ͳ͍ͷ!? ͬͯͳΓ·͢ΑͶɻ ϚδͰ͢ɻ 37
  38. ؾΛऔΓ௚ͯ͠ɻ ͜͜·Ͱ͸classΠϯελϯεͷϝϯόฤͰ͕ͨ͠ɺ ͔͜͜Β͸ϩʔΧϧείʔϓฤͰ͢ɻ func configureButtonAction() ͷதͰؔ਺Λ࡞Δύλʔϯɻ 38

  39. ϩʔΧϧfunction final class ViewController: UIViewController { func configureButtonAction() { func

    localFunc() { print("local func") } component.callback = localFunc } } ݁Ռ͸… 39
  40. ϩʔΧϧfunction final class ViewController: UIViewController { func configureButtonAction() { func

    localFunc() { print("local func") } component.callback = localFunc } } ݁Ռ: ݈શ! 40
  41. ϩʔΧϧfunction(தͰselfΛ࢖͏) final class ViewController: UIViewController { func configureButtonAction() { func

    localFuncUsingSelf() { print("local func using self", self) } component.callback = localFuncUsingSelf } } ݁Ռ͸… 41
  42. ϩʔΧϧfunction(தͰselfΛ࢖͏) final class ViewController: UIViewController { func configureButtonAction() { func

    localFuncUsingSelf() { print("local func using self", self) } component.callback = localFuncUsingSelf } } ݁Ռ: ॥؀ࢀর! 42
  43. ϩʔΧϧΫϩʔδϟ final class ViewController: UIViewController { func configureButtonAction() { let

    localClosure = { print("local closure") } component.callback = localClosure } } ݁Ռ͸… 43
  44. ϩʔΧϧΫϩʔδϟ final class ViewController: UIViewController { func configureButtonAction() { let

    localClosure = { print("local closure") } component.callback = localClosure } } ݁Ռ: ݈શ! 44
  45. ϩʔΧϧΫϩʔδϟ(தͰselfΛ࢖͏) final class ViewController: UIViewController { func configureButtonAction() { let

    localClosureUsingSelf = { print("local closure using self", self) } component.callback = localClosureUsingSelf } } ݁Ռ͸… 45
  46. ϩʔΧϧΫϩʔδϟ(தͰselfΛ࢖͏) final class ViewController: UIViewController { func configureButtonAction() { let

    localClosureUsingSelf = { print("local closure using self", self) } component.callback = localClosureUsingSelf } } ݁Ռ: ॥؀ࢀর! 46
  47. ϩʔΧϧΫϩʔδϟ(தͰunowned selfΛ࢖͏) final class ViewController: UIViewController { func configureButtonAction() {

    let localClosureUsingUnownedSelf = { [unowned self] in print("local closure using unowned self", self) } component.callback = localClosureUsingUnownedSelf } } ݁Ռ͸… 47
  48. ϩʔΧϧΫϩʔδϟ(தͰunowned selfΛ࢖͏) final class ViewController: UIViewController { func configureButtonAction() {

    let localClosureUsingUnownedSelf = { [unowned self] in print("local closure using unowned self", self) } component.callback = localClosureUsingUnownedSelf } } ݁Ռ: ݈શ! 48
  49. ͜͜·Ͱͷ·ͱΊ » ݈શ!ͳύλʔϯ » ϝιου([unowned self]ͳΫϩʔδϟ͔ΒݺͿ) » functionܕϓϩύςΟ » functionܕϓϩύςΟ(தͰselfΛ࢖͏)

    » ϩʔΧϧfunction » ϩʔΧϧΫϩʔδϟ » ϩʔΧϧΫϩʔδϟ(தͰunowned selfΛ࢖͏) » ॥؀ࢀর"͕ى͜Δύλʔϯ » ϝιουΛ௚઀౉͢ » ϩʔΧϧfunction(தͰselfΛ࢖͏) » ϩʔΧϧΫϩʔδϟ(தͰselfΛ࢖͏) 49
  50. ͞Βʹ·ͱΊ » Ϋϩʔδϟ͸ɺதͰ࢖ΘΕΔreference typeΛڧࢀরΩϟϓν ϟ͢Δ » unowned, weakΛ࢖͑͹ڧࢀরΩϟϓνϟ͸ආ͚ΒΕΔ » classΠϯελϯε͕࣋ͭϝιου͸ɺself΁ͷࢀরΛ࣋ͭ

    » classΠϯελϯε͕࣋ͭfunctionܕϓϩύςΟ͸ɺselfΛڧࢀ র͠ͳ͍ » தͰselfΛ࢖͏functionܕϓϩύςΟͰ͢ΒɺselfΛڧࢀর ͠ͳ͍ » Կނ…!? 50
  51. > தͰselfΛ࢖͏functionܕϓϩύςΟͰ͢ΒɺselfΛڧ ࢀর͠ͳ͍ …ຊ౰ʹʁ 51

  52. let functionTypePropertyUsingSelf = { print("function-type property using self", self) }

    self…? 52
  53. 53

  54. print("function-type property using self", self) ͷ݁Ռ (Function) …ͩͱ…!? 54

  55. functionܕϓϩύςΟ(தͰselfΛ࢖͏) …Λ΋͏Ұ౓Α͘Α͘ݟͯΈΔͱɺ final class ViewController: UIViewController { let functionTypePropertyUsingSelf =

    { print("function-type property using self", self) } } ! ͜ͷfunction͕࡞ΒΕΔ࣌ʹɺ ɹ self( ViewController )ͬͯ·ͩଘࡏͯ͠ͳ͘ͳ͍ʁ ɹ ଘࡏ͠ͳ͍΋ͷ͸ɺࢀর΋Ͱ͖ͳ͍ΑͶʁ 55
  56. ͪͳΈʹɺ ͜ͷselfΛऑࢀরΩϟϓνϟ͠Α͏ͱ͢Δͱ… final class ViewController: UIViewController { let functionTypePropertyUsingSelf =

    { [weak self] in print("function-type property using self", self) } } ऑࢀরʹͰ͖Δͷ͸ɺ classܕɺ͋Δ͍͸classܕઐ༻ͷϓϩτίϧ͚ͩɻ self͸ ViewController ܕͷΠϯελϯεͰ͸ͳ͍ͷͰɺ ऑࢀরΩϟϓνϟ΋ෆՄೳͬͯ͜ͱͰ͢Ͷɻ 56
  57. The Swift Programming Language (Swift 3): Closures ΑΓ Closure expressions

    are unnamed closures written in a lightweight syntax that can capture values from their surrounding context. surrounding contextͬͯͷ͸ɺͦ͏͍͏͜ͱ ʢͩͱࢥ͏ʣɻ 57
  58. ͞ΒʹͪͳΈʹɺ pure swiftͳclass (=NSObjectͷαϒΫϥεͰ͸ͳ͍) ͩͱ…… self͸ଘࡏࣗମɺͯ͠ͳ͍ʂ 58

  59. ·ͱΊʢ׬શ൛ʣ » Ϋϩʔδϟ͸ɺதͰ࢖ΘΕΔreference typeΛڧࢀ রΩϟϓνϟ͢Δ » unowned, weakΛ࢖͑͹ڧࢀরΩϟϓνϟ͸ආ ͚ΒΕΔ »

    classΠϯελϯε͕࣋ͭϝιου͸ɺself(classΠ ϯελϯε)΁ͷڧࢀরΛ࣋ͭɻ͠Όʔͳ͍ɻ » classΠϯελϯεͷfunctionܕϓϩύςΟͰ͸ɺͦ ΋ͦ΋self ≠ ॴ༗͍ͯ͠ΔclassΠϯελϯεࣗ਎ 59