簡體   English   中英

從 Form/NavigationView 中的閉包引用屬性並交換視圖時,SwiftUI 內存泄漏

[英]SwiftUI memory leak when referencing property from closure inside Form/NavigationView and swapping views

我有這樣的事情:

struct SomeView: View {
  @ObservedObject var viewModel: SomeViewModel

  var body: some View {
     NavigationView { // <- culprit
        Button(action: { self.viewModel.logOut() }) { Text("X").frame(width: 40, height: 40) }
     }
}

class SomeViewModel: ObservableObject {
  func logOut() {
  // changes global state, based on which the views are swapped, so `SomeView` is removed and replaced by a different one
  }
}

按下按鈕時, SomeView關閉並呈現不同的視圖。 但是如果我檢查內存圖, SomeViewModel仍然被分配,因為在 Button 的動作閉包中調用了 self.viewModel.logOut self.viewModel.logOut()並且 Button 持有對SomeViewModel的引用。

有什么辦法解決這個問題嗎?

編輯:實際上,當不在NavigationView中包裝按鈕時,沒有泄漏。 我一包裹按鈕,就會出現泄漏。 VStack中包裝效果很好。 但是用Form包裝會再次產生泄漏。 在這里似乎是同樣的問題: SwiftUI - Possible Memory Leak

我找到了一個解決方案:在您的操作中創建一個弱viewModel Apple 似乎改變了閉包的行為。 這意味着NavigationView正在存儲對 viewModel 的強引用。 經過幾天的調試,它終於對我有用了。

Button(action: { 
    [weak viewModel] in viewModel?.dismissButtonPressed.send(())
}) {
    Image("crossmark")
        .padding()
        .foregroundColor(Color.white)
    }
}

在您的問題中,這將像這樣解決:

NavigationView { 
    [weak viewModel] in Button(action: { viewModel?.logOut() }) {
        Text("X").frame(width: 40, height: 40)
    }
}

在最新的 Xcode 11.5 和 iOS 13.5 上進行了測試。 現在,在關閉視圖后, viewModel被正確釋放。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM