SwiftUI 保留循环与 .searchable

发布于 2025-01-13 12:43:51 字数 1519 浏览 0 评论 0原文

我想我在将可观察对象绑定到 .searchable 修饰符时发现了一个保留周期...

来验证:创建一个新的 swiftUI 应用程序;将 ContentView.swift 的内容替换为:

import SwiftUI

struct ContentView: View {
    
    var body: some View {
        NavigationView {
            List {
                NavigationLink("To Retain Cycle") {
                    RetainCycleView()
                }
            }
            .navigationTitle("Retain Cycle Demo")
        }
        .navigationViewStyle(.stack)
    }
}
    
struct RetainCycleView: View {
    
    @StateObject var model = Retainer()
//    @State var enteredText: String = ""
    
    var body: some View {
        VStack(alignment: .leading, spacing: 4) {
            Text("Navigate back to the previous view.")
            Text("You will see that 'Retainer' was NOT deallocated.")
            Text("(it's deinit function prints deallocing Retainer)")
                .font(.callout)
        }
        .padding()
        .searchable(text: $model.enteredText)
//       ^---- retain cycle
//        .searchable(text: $enteredText)
//       ^---- no retain cycle when using the @State var
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

class Retainer: ObservableObject {
    
    @Published var enteredText: String = ""
    
    init() { print("instantiated Retainer") }
    deinit { print("deallocing Retainer") }
}

当我从堆栈中弹出视图时,不会为 Retainer 调用 deinit。如果我删除 .searchable 修饰符,它的行为确实符合预期。

I think I found a retain cycle when binding an observable to a .searchable modifier...

to verify: create a new swiftUI app; replace ContentView.swift's content with this:

import SwiftUI

struct ContentView: View {
    
    var body: some View {
        NavigationView {
            List {
                NavigationLink("To Retain Cycle") {
                    RetainCycleView()
                }
            }
            .navigationTitle("Retain Cycle Demo")
        }
        .navigationViewStyle(.stack)
    }
}
    
struct RetainCycleView: View {
    
    @StateObject var model = Retainer()
//    @State var enteredText: String = ""
    
    var body: some View {
        VStack(alignment: .leading, spacing: 4) {
            Text("Navigate back to the previous view.")
            Text("You will see that 'Retainer' was NOT deallocated.")
            Text("(it's deinit function prints deallocing Retainer)")
                .font(.callout)
        }
        .padding()
        .searchable(text: $model.enteredText)
//       ^---- retain cycle
//        .searchable(text: $enteredText)
//       ^---- no retain cycle when using the @State var
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

class Retainer: ObservableObject {
    
    @Published var enteredText: String = ""
    
    init() { print("instantiated Retainer") }
    deinit { print("deallocing Retainer") }
}

When I pop the view off the stack, deinit won't be called for Retainer. If I remove the .searchable modifier, it does behave as expected.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文