内存调试器与LLDB对UINavigationController子控制器数量描述矛盾
内存调试器显示某UINavigationController实例包含1个ContactsTableViewController类型的子控制器,但在LLDB命令行中查询该导航控制器的viewControllers属性时,返回的数组元素数为0。
更新说明
- 捕获内存图与执行
po命令期间未执行其他操作。 - 以下是可复现该问题的Playground最小代码(仅在使用
UIViewControllerRepresentable.Coordinator时会触发此异常):
import PlaygroundSupport import SwiftUI import UIKit protocol Coordinator { var nav: UINavigationController { get } func start() } final class FlowCoordinator: Coordinator { struct Dependencies { let nav: UINavigationController let screen1Factory: () -> UIViewController let screen2Factory: () -> UIViewController } var nav: UINavigationController let screen1Factory: () -> UIViewController let screen2Factory: () -> UIViewController init(dependencies: FlowCoordinator.Dependencies) { self.nav = dependencies.nav self.screen1Factory = dependencies.screen1Factory self.screen2Factory = dependencies.screen2Factory } func start() { let vc = screen1Factory() as! ViewController vc.flowCoordinator = self nav.pushViewController(vc, animated: false) print("FlowCoordinator.started: flowCoordinator.nav: ", nav, "VCs count: ", nav.viewControllers.count) } func screen2() { print("Pushing screen2") let vc = screen2Factory() as! ViewController vc.flowCoordinator = self nav.pushViewController(vc, animated: false) print("Coordinator.viewController.flowCoordinator.nav: ", "VCs count: ", nav.viewControllers.count) } } final class ViewController: UITableViewController { weak var flowCoordinator: FlowCoordinator? // 表格视图要展示的城市数组 let cities = ["New York", "Paris", "Tokyo"] init() { super.init(nibName: nil, bundle: nil) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() tableView.register(UITableViewCell.self, forCellReuseIdentifier: "CityCell") } // MARK: - 表格视图数据源 override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // 返回分区的行数 return cities.count } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "CityCell", for: indexPath) // 配置单元格 cell.textLabel?.text = cities[indexPath.row] return cell } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { flowCoordinator?.screen2() } } final class AppDependencies { lazy var flowCoordinator: FlowCoordinator = { let navigationController = UINavigationController() navigationController.navigationBar.prefersLargeTitles = true let flowCoordinatorDependencies = FlowCoordinator.Dependencies( nav: navigationController, screen1Factory: makeViewController1, screen2Factory: makeViewController2) return FlowCoordinator(dependencies: flowCoordinatorDependencies) }() func makeViewController1() -> UIViewController { let vc = ViewController() vc.title = "View 1" return vc } func makeViewController2() -> UIViewController { let vc = ViewController() vc.title = "View 2" return vc } } struct View1: UIViewControllerRepresentable { let flowCoordinator: FlowCoordinator func makeUIViewController(context: Context) -> ViewController { return context.coordinator.viewController } func updateUIViewController(_ uiViewController: ViewController, context: Context) { } } extension View1 { final class Coordinator: NSObject, UITableViewDelegate { var viewController: ViewController var flowCoordinator: FlowCoordinator init(flowCoordinator: FlowCoordinator) { self.flowCoordinator = flowCoordinator self.flowCoordinator.start() self.viewController = self.flowCoordinator.nav.viewControllers.first as! ViewController super.init() viewController.tableView.delegate = self } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { print("View1.tableView(_:didSelectRowAt:indexPath)") print("Coordinator.viewController.flowCoordinator.nav: ", viewController.flowCoordinator?.nav ?? "nil", "VCs count: ", viewController.flowCoordinator?.nav.viewControllers.count ?? "nil") viewController.flowCoordinator?.screen2() } } func makeCoordinator() -> Coordinator { return Coordinator(flowCoordinator: flowCoordinator) } } struct ContentView: View { let deps = AppDependencies() var body: some View { View1(flowCoordinator: deps.flowCoordinator) } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } let deps = AppDependencies() //deps.flowCoordinator.start() let nav = deps.flowCoordinator.nav //let host = nav let host = UIHostingController(rootView: View1(flowCoordinator: deps.flowCoordinator) ) PlaygroundPage.current.liveView = host
内容的提问来源于stack exchange,提问作者onthemoon
相关产品推荐
相关产品推荐

