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

メモリー管理の嬉しいバイキング料理

Ray Fix
August 20, 2016

 メモリー管理の嬉しいバイキング料理

Swiftの初心者の中には、自動参照カウントを使えば、メモリー管理は気にしなくても良いと認識している方が多くいます。確かにSwiftは、ごみ収集システムを使うより、予測可能性は高いと言えます。しかし自動参照カウントを使用する際は、メモリー構造を意識する必要があります。ユーザーは、幾つかの方法でメモリー構造の落とし穴を避けることができます。今回のトークでは、メモリーの取り扱い方法について分かりやく説明します。

Ray Fix

August 20, 2016
Tweet

More Decks by Ray Fix

Other Decks in Programming

Transcript

  1. iosdc.jp Ray Fix ελοΫ ελοΫ͸ͱʹ͔͘଎͍ʂ func candy() { let ramune

    = 10 let pocky = 12 let gummi = 20 } ελοΫ 10 12 20
  2. iosdc.jp Ray Fix ελοΫ ελοΫ͸ͱʹ͔͘଎͍ʂ func candy() { let ramune

    = 10 let pocky = 12 let gummi = 20 } ελοΫ ϩοΫ͢Δඞཁ͸શ͘ͳ͍
  3. iosdc.jp Ray Fix ώʔϓྖҬ class Dishɹ{ var name: String init(name:

    String) { self.name = name print(" Dish \(name)") } deinit { print("☠ Dish \(name)") } }
  4. iosdc.jp Ray Fix ώʔϓྖҬ let softCream = Dish(name: “Soft Cream")

    Count: 1 “Soft Cream” ώʔϓ softCream ελοΫ
  5. iosdc.jp Ray Fix ώʔϓྖҬ let softCream = Dish(name: “Soft Cream")

    Count: 1 “Soft Cream” softCream ώʔϓ ελοΫ
  6. iosdc.jp Ray Fix ώʔϓྖҬ let softCream = Dish(name: “Soft Cream")

    let special = softCream Count: 1 “Soft Cream” softCream ώʔϓ ελοΫ
  7. iosdc.jp Ray Fix ώʔϓྖҬ let softCream = Dish(name: “Soft Cream")

    let special = softCream Count: 1 “Soft Cream” softCream ώʔϓ ελοΫ Count: 2 “Soft Cream” special
  8. iosdc.jp Ray Fix ڞ༗ softCream.name = "Choco Soft Cream" special.name

    // "Choco Soft Cream" ϫΦɺศརʂʂʂ ͔͠͠
  9. iosdc.jp Ray Fix ڞ༗ softCream.name = "Choco Soft Cream" special.name

    // "Choco Soft Cream" ϫΦɺศརʂʂʂ ͔͠͠ special.name = "ϐʔϚϯ" softCream.name // "ϐʔϚϯ"
  10. iosdc.jp Ray Fix ڞ༗ softCream.name = "Choco Soft Cream" special.name

    // "Choco Soft Cream" ϫΦɺศརʂʂʂ ͔͠͠ special.name = "ϐʔϚϯ" softCream.name // "ϐʔϚϯ" ૝ఆ֎ͷڞ༗͸ࢀরܕͷܽ఺
  11. iosdc.jp Ray Fix ղܾ๏:ఆ਺Λ࢖͏ class Dishɹ{ init(name: String) { self.name

    = name print(" Dish \(name)") } deinit { print("☠ Dish \(name)") } } var name: String
  12. iosdc.jp Ray Fix ղܾ๏:ఆ਺Λ࢖͏ class Dishɹ{ init(name: String) { self.name

    = name print(" Dish \(name)") } deinit { print("☠ Dish \(name)") } } var name: String
  13. iosdc.jp Ray Fix ղܾ๏:ఆ਺Λ࢖͏ class Dishɹ{ init(name: String) { self.name

    = name print(" Dish \(name)") } deinit { print("☠ Dish \(name)") } } let name: String
  14. iosdc.jp Ray Fix ղܾ๏:ఆ਺Λ࢖͏ class Dishɹ{ init(name: String) { self.name

    = name print(" Dish \(name)") } deinit { print("☠ Dish \(name)") } } let name: String special.name = "ϐʔϚϯ"
  15. iosdc.jp Ray Fix ώʔϓྖҬ let softCream = Dish(name: “Soft Cream")

    let special = softCream Count: 0 “Soft Cream” ώʔϓ ελοΫ Count: 2 “Soft Cream” softCream special
  16. iosdc.jp Ray Fix ώʔϓྖҬ let softCream = Dish(name: “Soft Cream")

    let special = softCream Count: 0 “Soft Cream” ώʔϓ ελοΫ
  17. iosdc.jp Ray Fix ࢀরαΠΫϧ class Customer { var orders: [Order]

    func add(order: Order) { order.customer = self orders.append(order) } } class Order { var customer: Customer? let dish: Dish }
  18. iosdc.jp Ray Fix ࢀরαΠΫϧ class Customer { var orders: [Order]

    func add(order: Order) { order.customer = self orders.append(order) } } class Order { var customer: Customer? let dish: Dish }
  19. iosdc.jp Ray Fix ࢀরαΠΫϧ let ray = Customer(name: "Ray") let

    saikoro = Dish(name: “Saikoro Steak") let order = Order(dish: saikoro) ray.add(order: order)
  20. iosdc.jp Ray Fix ࢀরαΠΫϧ let ray = Customer(name: "Ray") let

    saikoro = Dish(name: “Saikoro Steak") let order = Order(dish: saikoro) ray.add(order: order) ray saikoro order orders
  21. iosdc.jp Ray Fix ࢀরαΠΫϧ let ray = Customer(name: "Ray") let

    saikoro = Dish(name: “Saikoro Steak") let order = Order(dish: saikoro) ray.add(order: order) ray saikoro order orders
  22. iosdc.jp Ray Fix ॥؀ࢀর class Customer { var orders: [Order]

    func add(order: Order) { order.customer = self orders.append(order) } } class Order { let dish: Dish } var customer: Customer?
  23. iosdc.jp Ray Fix ॥؀ࢀর class Customer { var orders: [Order]

    func add(order: Order) { order.customer = self orders.append(order) } } class Order { let dish: Dish } var customer: Customer? weak
  24. iosdc.jp Ray Fix ॥؀ࢀর class Customer { var orders: [Order]

    func add(order: Order) { order.customer = self orders.append(order) } } class Order { let dish: Dish } var customer: Customer? weak
  25. iosdc.jp Ray Fix ॥؀ࢀর let ray = Customer(name: "Ray") let

    saikoro = Dish(name: "Saikoro") let order = Order(dish: saikoro) ray.add(order: order) ray saikoro order orders
  26. iosdc.jp Ray Fix ॥؀ࢀর let ray = Customer(name: "Ray") let

    saikoro = Dish(name: "Saikoro") let order = Order(dish: saikoro) ray.add(order: order) ray saikoro order orders
  27. iosdc.jp Ray Fix ॥؀ࢀর let ray = Customer(name: "Ray") let

    saikoro = Dish(name: "Saikoro") let order = Order(dish: saikoro) ray.add(order: order) saikoro order nil
  28. iosdc.jp Ray Fix ॥؀ࢀর let ray = Customer(name: "Ray") let

    saikoro = Dish(name: "Saikoro") let order = Order(dish: saikoro) ray.add(order: order) saikoro
  29. iosdc.jp Ray Fix ॥؀ࢀর let ray = Customer(name: "Ray") let

    saikoro = Dish(name: "Saikoro") let order = Order(dish: saikoro) ray.add(order: order)
  30. iosdc.jp Ray Fix weak nil nil nil ࢀর̍ ࢀর̎ ࢀর̏

    reference value ࢀর̍ nil ࢀর̎ nil ࢀর̏ nil άϩʔόϧςʔϒϧ
  31. iosdc.jp Ray Fix Swift weak 1 3 0 κϯϏ 3

    ࢀর̎ ࢀর̏ ࢀর̍
  32. unowned class Order { let dish: Dish } class Customer

    { var orders: [Order] func add(dish: Dish) { let order = Order(dish: dish, customer: self) orders.append(order) } } let customer: Customer
  33. unowned class Order { let dish: Dish } class Customer

    { var orders: [Order] func add(dish: Dish) { let order = Order(dish: dish, customer: self) orders.append(order) } } let customer: Customer
  34. unowned class Order { let dish: Dish } class Customer

    { var orders: [Order] func add(dish: Dish) { let order = Order(dish: dish, customer: self) orders.append(order) } } let customer: Customer unowned
  35. unowned class Order { let dish: Dish } class Customer

    { var orders: [Order] func add(dish: Dish) { let order = Order(dish: dish, customer: self) orders.append(order) } } let customer: Customer unowned
  36. iosdc.jp Ray Fix unowned 1 3 0 κϯϏ 3 ࢀর̎

    ࢀর̏ ࢀর̍ ϓϩάϥϜ͕ఀࢭ
  37. ྫɿण࢘԰ enum MenuItem: String { case toro, ebi, anago, uni,

    ikura, hamachi } typealias Action = ()->()
  38. ྫɿ ण࢘԰ class Sushiya { lazy var menu: [MenuItem: Action]

    = […] func prepare(_ menuItem: MenuItem) { menu[menuItem]?() } private func serve(dish: Dish) { print("Now serving \(dish.name)") } }
  39. ྫɿ ण࢘԰ menu = [ .toro: { let dish =

    Dish(name: "Toro") }, … ] serve(dish: dish)
  40. ྫɿ ण࢘԰ menu = [ .toro: { let dish =

    Dish(name: "Toro") }, … ] serve(dish: dish) self.
  41. ྫɿ ण࢘԰ menu = [ .toro: { let dish =

    Dish(name: "Toro") }, … ] serve(dish: dish) self. let sushiya = Sushiya() sushiya.prepare(.toro)
  42. ղܾ๏ɿ ΩϟϓνϟʔϦετ var value = 0 let showValue = {

    print(value) } showValue() // prints 0 value = 10 showValue() // prints 10
  43. ղܾ๏ɿ ΩϟϓνϟʔϦετ var value = 0 let showValue = {

    print(value) } showValue() // prints 0 value = 10 showValue() // prints 10
  44. ղܾ๏ɿ ΩϟϓνϟʔϦετ var value = 0 let showValue = {

    print(value) } showValue() // prints 0 value = 10 showValue() // prints [value] in 10
  45. ղܾ๏ɿ ΩϟϓνϟʔϦετ var value = 0 let showValue = {

    print(value) } showValue() // prints 0 value = 10 showValue() // prints [value] in 0
  46. ղܾ๏ɿ ΩϟϓνϟʔϦετ menu = [ .toro: { let dish =

    Dish(name: "Toro") self.serve(dish: dish) }, … ]
  47. ղܾ๏ɿ ΩϟϓνϟʔϦετ menu = [ .toro: { let dish =

    Dish(name: "Toro") self.serve(dish: dish) }, … ] [unowned self] in #
  48. ඇಉظͷ໰୊ private func serve(dish: Dish) { DispatchQueue.main.async { print("Now serving

    \(dish.name)") self.served += 1 } } private func serve(dish: Dish) { print("Now serving \(dish.name)") }
  49. ඇಉظͷ໰୊ [unowned self] in private func serve(dish: Dish) { DispatchQueue.main.async

    { print("Now serving \(dish.name)") self.served += 1 } } private func serve(dish: Dish) { print("Now serving \(dish.name)") }
  50. ඇಉظͷ໰୊ [unowned self] in private func serve(dish: Dish) { DispatchQueue.main.async

    { print("Now serving \(dish.name)") self.served += 1 } } private func serve(dish: Dish) { print("Now serving \(dish.name)") } CRASH!!!!
  51. ඇಉظͷ໰୊ private func serve(dish: Dish) { DispatchQueue.main.async { print("Now serving

    \(dish.name)") self.served += 1 } } private func serve(dish: Dish) { print("Now serving \(dish.name)") }
  52. weak private func serve(dish: Dish) { DispatchQueue.main.async { [weak self]

    in print("Now serving \(dish.name)") self?.served += 1 } }
  53. strong weak μϯε private func serve(dish: Dish) { DispatchQueue.main.async {

    [weak self] in guard let strongSelf = self else { print("Cancelled \(dish.name)") return } print("Now serving \(dish.name)") strongSelf.served += 1 } }
  54. https://www.youtube.com/watch?v=0-vWT-t0UHg ԣ඿ϦφοΫεಡॻձ̒̓ɿmalloc https://www.mikeash.com/pyblog/friday-qa-2015-12-11-swift-weak-references.html SWIFT ऑ͍ࢀরͷৄ͍͠࿩ http://bit.ly/etystamp ༑ୡͷ LINE ελϜϓʂ https://en.wikipedia.org/wiki/La_Jolla

    ೆΧϦϑΥϧχΞͷࣸਅ https://ja.wikipedia.org/wiki/ण࢘ ण࢘ͷࣸਅ http://echo-labs.com/ ECHO LABS ݦඍڸ http://raywenderlich.com/ Ray Wenderlich ϝϞϦʔνϡʔτ (Maxime Defauwஶऀ) 9݄ެ։༧ఆ ࢀߟϦϯΫ https://github.com/rayfix/MemoryDish ιʔείʔυɺεϥΠυ wwdc2016/416/ WWDC Swift Performance
  55. https://www.youtube.com/watch?v=0-vWT-t0UHg ԣ඿ϦφοΫεಡॻձ̒̓ɿmalloc https://www.mikeash.com/pyblog/friday-qa-2015-12-11-swift-weak-references.html SWIFT ऑ͍ࢀরͷৄ͍͠࿩ http://bit.ly/etystamp ༑ୡͷ LINE ελϜϓʂ https://en.wikipedia.org/wiki/La_Jolla

    ೆΧϦϑΥϧχΞͷࣸਅ https://ja.wikipedia.org/wiki/ण࢘ ण࢘ͷࣸਅ http://echo-labs.com/ ECHO LABS ݦඍڸ http://raywenderlich.com/ Ray Wenderlich ϝϞϦʔνϡʔτ (Maxime Defauwஶऀ) 9݄ެ։༧ఆ ࢀߟϦϯΫ https://github.com/rayfix/MemoryDish ιʔείʔυɺεϥΠυ wwdc2016/416/ WWDC Swift Performance