提问人:Shivaditya kr 提问时间:11/16/2023 最后编辑:Brian Tompsett - 汤莱恩Shivaditya kr 更新时间:11/16/2023 访问量:40
在 UIKit 中将 SwiftUI 与 API 调用和导航结合使用时出现内存泄漏问题
Memory Leak Issue when Using SwiftUI in UIKit with API Calls and Navigation
问:
我在基于 UIKit 的 App 中的 SwiftUI 实现中遇到了内存泄漏问题。我正在使用 UIKit 视图控制器中嵌入的 SwiftUI 视图,在执行 API 调用和在视图控制器之间导航时会出现问题。
下面是代码结构的简化版本:
protocol SampleDelegate: AnyObject {
func push()
func pop()
}
class SampleVC: UIViewController, SampleDelegate {
var viewModel: SampleVM!
override func viewDidLoad() {
super.viewDidLoad()
let swiftUIView = SampleView(viewModel: viewModel)
let hostingController = UIHostingController(rootView: swiftUIView)
self.addChild(hostingController)
self.view.addSubview(hostingController.view)
hostingController.didMove(toParent: self)
hostingController.view.translatesAutoresizingMaskIntoConstraints = false
// Set up Auto Layout constraints for the SwiftUI view
NSLayoutConstraint.activate([
hostingController.view.topAnchor.constraint(equalTo: view.topAnchor),
hostingController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
hostingController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor),
hostingController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
// Use of viewmodel for making api controll on viewcontroller (UiKit)
self.bindData()
}
func bindData() {
viewModel.error.bind { error in
Toast.showError(error: error ?? NetworkError.somethingWentWrong)
}
}
func push() {
// push new viewcontroller
}
func pop() {
// pop viewcontroller
}
}
class SampleVM: ObservableObject {
@Published var fetchCompletion = false
var error: Observable<Error?> = Observable(nil)
func fetchData() {
// call api to fetch and change fetched
}
}
struct SampleView: View {
@ObservedObject var viewModel: SampleVM
weak var delegate: SampleDelegate?
init(viewModel: SampleVM, delegate: SampleDelegate? = nil) {
self.viewModel = viewModel
self.delegate = delegate
}
var body: some View {
VStack {
Text("\((viewModel.fetchCompletion == true) ? "fetching" : "fetched")")
Spacer()
HStack {
Button {
delegate?.pop()
} label: {
Text("pop")
}
Button {
delegate?.push()
} label: {
Text("push")
}
}
}
}
}
该问题似乎与内存使用有关,尤其是在推送和弹出视图控制器时。每次重复执行这些操作时,应用程序的内存占用量都会增加,这表明存在潜在的内存泄漏。
我已经确保在必要时使用 [weak self],并检查了 SwiftUI 视图层次结构中的强引用周期,但问题仍然存在。
有关如何排除和解决此内存泄漏问题的任何见解或建议将不胜感激。
已检查 SwiftUI 视图层次结构中的强引用周期。 实施了 [弱自我] 以防止闭包中的保留循环。 查看了 SwiftUI 和 UIKit 互操作性指南。 此外,我从子视图中删除了hostingview,同时弹出了同样不起作用的控制器。
答:
0赞
lorem ipsum
11/16/2023
#1
委托在 SwiftUI 视图中不能很好地工作,将委托引用放在视图模型中。
SwiftUI 视图是值类型,并且存在不明显的底层存储。
SwiftUI 可以随意重新创建视图,除非属性的值位于 SwiftUI 的值中,否则它无法保持其完整性/引用。
视图模型之所以有效,是因为告诉 SwiftUI 不要分配储存空间,因为它是在其他地方维护的。@ObservedObject
评论