90: 動態尋找成員

weak self podcast

線上收聽與節目筆記

簡短介紹一個超實用的 Swift 冷門技巧。寫 SwiftUI 很有機會用到。

👋開場 & 節目回顧

再補充一下 weak self Discord 的玩法。請按我加入(每集更新連結)。

⭐️@dynamicMemberLookup

  • 常用情境:model 需要被拓展,但不能或不想用繼承的方式
struct FooModel {
  var string: String
}

@dynamicMemberLookup
struct FooWrapper {
  var wrapped: FooModel

  subscript<Value>(dynamicMember keyPath: KeyPath<FooModel, Value>) -> Value {
    wrapped[keyPath: keyPath]
  }
}

// 使用:可直接取用 wrapped 裡的 property
let string = FooWrapper().string
  • 或者做成 generic 的版本
@dynamicMemberLookup
struct AnyWrapper<T> {
  var wrapped: T

  subscript<Value>(dynamicMember keyPath: KeyPath<T, Value>) -> Value {
    wrapped[keyPath: keyPath]
  }
}
  • 要支援寫入則需要用到WritableKeyPath
  subscript<Value>(dynamicMember keyPath: WritableKeyPath<T, Value>) -> Value {
    get {
      wrapped[keyPath: keyPath]
    }
    set {
      wrapped[keyPath: keyPath] = newValue
    }
  }
  • 13 提到的 generic id wrapper,看請況可用在 SwiftUI 的 ForEach 使用
struct IdentifiableWrapper<T>: Identifiable {
  let id = UUID()
  var wrapped: T

  init(_ wrapped: T) {
    self.wrapped = wrapped
  }
}

struct Model {
  var title: String
}

// 使用方式:再適當的時機用 wrapper 包起來
// 請不要在 SwiftUI 裡面做 .map,因為 id 要盡可能保持一致
let models = [Model(title: "標題")...].map(IdentifiableWrapper.init)

// 再送至 SwiftUI 的 ForEach 使用
ForEach(models) {
  Text($0.wrapped.title)
}
  • Generic id wrapper 的 @dynamicMemberLookup 的版本
@dynamicMemberLookup
struct IdentifiableWrapper<T>: Identifiable {
  let id = UUID()
  var wrappedValue: T

  init(_ wrappedValue: T) {
    self.wrappedValue = wrappedValue
  }

  subscript<Value>(dynamicMember keyPath: KeyPath<T, Value>) -> Value {
    wrappedValue[keyPath: keyPath]
  }
}

// 這段同上
struct Model {
  var title: String
}

// 這段同上
let models = [Model(title: "標題")...].map(IdentifiableWrapper.init)

// 再送至 SwiftUI 的 ForEach 使用,不用再寫 .wrapped 便可使用
ForEach(models) {
  Text($0.title)
}
  • 嵌套的 @dynamicMemberLookup 是可行的
  • property name 相同的話,會取上層的

💸勸敗話題

  • 預告:Swift Playgrounds 4 還來不及深入研究,有機會再聊
  • 13:腦航員2
  • Pofat:地獄之刃
  • 兩款都在 XGP 裡,充分發揮低成本試錯的優點
  • 擁有選擇權

👋收尾 & 預告

  • 預告:喬喬回歸

更多 weak self


weak self podcast logo

weak self podcast

集結弱弱的我,也可以組成強大的社群。在 iOS 開發圈打滾的台灣工程師,專為 Apple & iOS 開發者而製作的 Podcast。主持人一三波肥。內容涵蓋了 iOS 與 Apple 開發圈的新知討論、踩坑經驗、人物採訪、社群活動、職場生活。

回首頁聽眾朋友怎麼說?weak self 歷史

線上收聽

可使用 OvercastListen NotesGoogle Podcasts 網站。

訂閱方式

weak self 支援任何 podcast 播放軟體,只要訂閱我們的 RSS 網址即可。

Listen on Apple Podcasts Listen on Google Podcasts Listen on Overcast Listen on Pocket Casts Listen on Spotify Listen in Castro

贊助 weak self

謝謝,請見說明