SwiftUI 中的记忆?
Posted
技术标签:
【中文标题】SwiftUI 中的记忆?【英文标题】:Memoization in SwiftUI? 【发布时间】:2020-03-27 20:09:45 【问题描述】:我来自 React,我使用 useMemo
来确保不会经常执行某些计算。我如何在 SwiftUI 中做这样的事情?
考虑这个例子:
struct MyView: View
var records: [Record]
var body: some View
Text("expensive summary: \(self.expensiveSummary)")
var expensiveSummary: String
// based on records, return string
// containing a summary of records
return ""
有什么方法可以确保我的 expensiveSummary
仅在我的记录数组更改时被调用?
【问题讨论】:
我们可以假设父视图正在传入records
并且会发生变化。
【参考方案1】:
这是作为EquatableView
内置的。
struct MyView: EquatableView ...
这只会在 body
的属性(在本例中为 records
)实际发生变化时重新计算 expensiveSummary
,这将阻止重新评估 expensiveSummary
。
这不会避免对expensiveSummary
inside 的body
进行多次评估。如果您需要缓存此类信息,您通常应该创建一个局部变量(尽管有时函数构建器语法不允许这样做,除非将部分代码提取到单独的函数中),或者在init
中计算一个属性。
作为风格问题,我建议不要计算属性的评估成本过高。这令人困惑,因为属性语法通常表明该操作很便宜。相反,我建议这是一个函数或在 init
中计算一次。
【讨论】:
【参考方案2】:我认为我们可以将包装视图创建为Equatable
。
(也许,我们可以使用EquatableView
或.equatable()
修饰符吗?)
struct UseMemo<KeyType: Equatable, ViewType: View>: View, Equatable
let key: KeyType
let content: (KeyType) -> ViewType
var body: some View
content(key)
static func ==(lhs: UseMemo, rhs: UseMemo) -> Bool
return lhs.key == rhs.key
struct MyView: View
@State var records: [Int] = (Array<Int>)(1...10000)
@State var other = false
var body: some View
VStack
Button("Update other", action: self.other.toggle() )
Text("Other: \(String(other))") // This will be called everytime
Button("Update records", action: self.records.append(1) )
UseMemo(key: records) keys in
// This is not called even if updated "other"
// This is called when updates "records"
Text("expensive summary: \(expensiveSummary)")
// This will be called everytime
Text("expensive summary: \(expensiveSummary)")
var expensiveSummary: String
String(records.randomElement()!)
以下内容对我有帮助。
SwiftUI — Why should you write as many custom views for better performance SwiftUI: prevent View from refreshing when presenting a sheet【讨论】:
以上是关于SwiftUI 中的记忆?的主要内容,如果未能解决你的问题,请参考以下文章
如何知道 UIKit 视图控制器中的 swiftUI 事件? ||如何提供 swiftUI 和 uikit 之间的通信
如何将我的自定义 ButtonStyle 添加到 swiftui3 中的快捷方式 swiftui .buttonstyle() 属性