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. ϝϞϦʔ؅ཧͷඒຯ͍͠
    όΠΩϯάྉཧ
    Ray Fix
    @rayfix
    ը૾ఏڙ Yumi Kimura (CC2)

    View full-size slide

  2. Ray Fix͸୭ʁ
    Source: https://en.wikipedia.org/wiki/La_Jolla

    View full-size slide

  3. RayWenderlich.com

    View full-size slide

  4. iosdc.jp Ray Fix

    View full-size slide

  5. iosdc.jp Ray Fix

    View full-size slide

  6. iosdc.jp Ray Fix
    ϝϞϦʔ؅ཧ

    View full-size slide

  7. iosdc.jp Ray Fix
    ελοΫvsώʔϓྖҬ

    View full-size slide

  8. iosdc.jp Ray Fix
    ελοΫ
    ελοΫ͸ͱʹ͔͘଎͍ʂ

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  13. iosdc.jp Ray Fix
    ελοΫ
    ελοΫ͸ͱʹ͔͘଎͍ʂ
    func candy() {
    let ramune = 10
    let pocky = 12
    let gummi = 20
    }
    ελοΫ
    ϩοΫ͢Δඞཁ͸શ͘ͳ͍

    View full-size slide

  14. iosdc.jp Ray Fix
    ώʔϓྖҬ
    class Dishɹ{
    var name: String
    init(name: String) {
    self.name = name
    print(" Dish \(name)")
    }
    deinit {
    print("☠ Dish \(name)")
    }
    }

    View full-size slide

  15. iosdc.jp Ray Fix
    ώʔϓྖҬ

    View full-size slide

  16. iosdc.jp Ray Fix
    ώʔϓྖҬ
    let softCream = Dish(name: “Soft Cream")

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  22. iosdc.jp Ray Fix
    ڞ༗
    softCream.name = "Choco Soft Cream"
    special.name // "Choco Soft Cream"

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  26. iosdc.jp Ray Fix
    ڞ༗
    softCream.name = "Choco Soft Cream"
    special.name // "Choco Soft Cream"
    ϫΦɺศརʂʂʂ
    ͔͠͠
    special.name = "ϐʔϚϯ"
    softCream.name // "ϐʔϚϯ"
    ૝ఆ֎ͷڞ༗͸ࢀরܕͷܽ఺

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  34. iosdc.jp Ray Fix
    Customer
    orders
    ໰୊ɿ॥؀ࢀর
    Order
    customer
    dish
    Dish
    name

    View full-size slide

  35. 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
    }

    View full-size slide

  36. 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
    }

    View full-size slide

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

    View full-size slide

  38. 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

    View full-size slide

  39. 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

    View full-size slide

  40. iosdc.jp Ray Fix
    Xcode 8 Memory Visualizer

    View full-size slide

  41. iosdc.jp Ray Fix
    Xcode 8 Memory Visualizer

    View full-size slide

  42. iosdc.jp Ray Fix
    Xcode 8 Memory Visualizer

    View full-size slide

  43. iosdc.jp Ray Fix
    Xcode 8 Memory Visualizer

    View full-size slide

  44. iosdc.jp Ray Fix
    Xcode 8 Memory Visualizer

    View full-size slide

  45. iosdc.jp Ray Fix
    Customer
    orders
    ॥؀ࢀর
    Order
    customer
    dish
    Dish
    name

    View full-size slide

  46. 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?

    View full-size slide

  47. 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

    View full-size slide

  48. 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

    View full-size slide

  49. 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

    View full-size slide

  50. 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

    View full-size slide

  51. 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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  54. iosdc.jp Ray Fix
    weak
    ࢀর̍
    ࢀর̎
    ࢀর̏

    View full-size slide

  55. iosdc.jp Ray Fix
    weak
    ࢀর̍
    ࢀর̎
    ࢀর̏

    View full-size slide

  56. iosdc.jp Ray Fix
    weak
    ࢀর̍
    ࢀর̎
    ࢀর̏

    View full-size slide

  57. iosdc.jp Ray Fix
    weak
    nil
    nil
    nil
    ࢀর̍
    ࢀর̎
    ࢀর̏

    View full-size slide

  58. iosdc.jp Ray Fix
    weak
    nil
    nil
    nil
    ࢀর̍
    ࢀর̎
    ࢀর̏
    reference value
    ࢀর̍ nil
    ࢀর̎ nil
    ࢀর̏ nil
    άϩʔόϧςʔϒϧ

    View full-size slide

  59. iosdc.jp Ray Fix
    Swift weak
    1 3
    ࢀর̎
    ࢀর̏
    ࢀর̍

    View full-size slide

  60. iosdc.jp Ray Fix
    Swift weak
    1 3
    ࢀর̎
    ࢀর̏
    ࢀর̍

    View full-size slide

  61. iosdc.jp Ray Fix
    Swift weak
    1 3
    0 κϯϏ 3
    ࢀর̎
    ࢀর̏
    ࢀর̍

    View full-size slide

  62. ڧ͍ࢀরΧ΢ϯτ͕̌ʹ

    View full-size slide

  63. ڧ͍ࢀরΧ΢ϯτ͕̌ʹ

    View full-size slide

  64. ऑ͍ࢀরΧ΢ϯτ͕̌ʹ

    View full-size slide

  65. ऑ͍ࢀরΧ΢ϯτ͕̌ʹ

    View full-size slide

  66. unowned
    • unowned ͸ผͷछྨͷऑ͍ࢀর
    • ࢀরઌ͕ඞͣ͋Δ͜ͱ͕લఏ
    • ΋͠ࢀরઌ͕ͳ͍ͱɺϓϩάϥϜ͕ఀࢭ͢Δ

    View full-size slide

  67. 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

    View full-size slide

  68. 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

    View full-size slide

  69. 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

    View full-size slide

  70. 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

    View full-size slide

  71. iosdc.jp Ray Fix
    unowned
    1 3
    0 κϯϏ 3
    ࢀর̎
    ࢀর̏
    ࢀর̍

    View full-size slide

  72. iosdc.jp Ray Fix
    unowned
    1 3
    0 κϯϏ 3
    ࢀর̎
    ࢀর̏
    ࢀর̍
    ϓϩάϥϜ͕ఀࢭ

    View full-size slide

  73. ؔ਺ͱΫϩʔδϟ΋ࢀরܕ
    { }

    View full-size slide

  74. ؔ਺ͱΫϩʔδϟ΋ࢀরܕ
    { }

    View full-size slide

  75. ྫɿण࢘԰
    enum MenuItem: String {
    case toro, ebi, anago, uni, ikura, hamachi
    }
    typealias Action = ()->()

    View full-size slide

  76. ྫɿ ण࢘԰
    class Sushiya {
    lazy var menu: [MenuItem: Action] = […]
    func prepare(_ menuItem: MenuItem) {
    menu[menuItem]?()
    }
    private func serve(dish: Dish) {
    print("Now serving \(dish.name)")
    }
    }

    View full-size slide

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

    ]
    serve(dish: dish)

    View full-size slide

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

    ]
    serve(dish: dish)
    self.

    View full-size slide

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

    ]
    serve(dish: dish)
    self.
    let sushiya = Sushiya()
    sushiya.prepare(.toro)

    View full-size slide

  80. ϝϞϦʔ࿙Ε

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    ]

    View full-size slide

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

    ]
    [unowned self] in
    #

    View full-size slide

  88. ඇಉظͷ໰୊
    private func serve(dish: Dish) {
    print("Now serving \(dish.name)")
    }

    View full-size slide

  89. ඇಉظͷ໰୊
    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)")
    }

    View full-size slide

  90. ඇಉظͷ໰୊
    [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)")
    }

    View full-size slide

  91. ඇಉظͷ໰୊
    [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!!!!

    View full-size slide

  92. ඇಉظͷ໰୊
    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)")
    }

    View full-size slide

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

    View full-size slide

  94. 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
    }
    }

    View full-size slide

  95. ඒຯ͍͠SWIFTΛॻ͘ʹ͸
    ϝϞϦʔͱͷ૬ੑΛ
    ೺Ѳ͢Δඞཁ͕͋Δ

    View full-size slide

  96. ͝ਗ਼ௌ͋Γ͕ͱ͏
    ͍͟͝·ͨ͠

    View full-size slide

  97. 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

    View full-size slide

  98. 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

    View full-size slide