代码之家  ›  专栏  ›  技术社区  ›  Santiago Padilla

UIkit ChildController保留周期

  •  0
  • Santiago Padilla  · 技术社区  · 3 年前

    嗨,我正在制作一个应用程序,我使用类似tableView的Apples Settings应用程序。我在各种控制器中使用这个表视图,所以我制作了一个控制器,将其作为子控制器添加到需要使用该表视图的控制器中。

    它之所以是子控制器,是因为它需要在多个控制器中重复使用表的布局和功能。

    我遇到的问题是添加一个子控制器会将控制器保留在内存中。

    以下是如何在主控制器消失之前移除子控制器:

    guard parent != nil else { return }
            
            willMove(toParent: nil)
            removeFromParent()
            view.removeFromSuperview()
    

    以下是我将子控制器添加到主控制器的方式:

        addChild(controller)
        controller.view.frame = self.view.frame
        view.addSubview(controller.view)
        controller.didMove(toParent: self)
    

    子控制器:

    class ChildController: UIViewController {
        
        //MARK: - Propeties
        public var sections: [FormSection_Model] = [] {
            didSet {
                tableView.reloadData()
            }
        }
        
        public private(set) lazy var tableView: UITableView = {
            return UITableView(frame: .zero, style: style)
        }()
        
        override func setUp() {
            super.setUp()
            
            hideKeyboardWhenTappedAround()
            
            tableView.dataSource = self
            tableView.delegate = self
            
            tableView.register(ButtonForm_Cell.self)
            tableView.register(SwitchForm_Cell.self)
            tableView.register(TextFieldForm_Cell.self)
            tableView.register(TextViewForm_Cell.self)
            tableView.register(PickerForm_Cell.self)
            tableView.register(MultiPickerForm_Cell.self)
            tableView.register(LinkForm_Cell.self)
            tableView.contentInsetAdjustmentBehavior = .never
        }
        
        override func setUpLayout() {
            super.setUpLayout()
            
            view.addSubview(tableView)
            tableView.frame = view.frame
            tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 150, right: 0)
        }
    }
    
    extension ChilsController: UITableViewDelegate, UITableViewDataSource {
        //TableView delegate funcs...
    }
    

    主控制器:

     class Controller: UIViewController {
        
        public private(set) lazy var formController: ChildController = {
            let controller = FormTableView_Controller(style: .insetGrouped)
            return controller
        }()
        
        override func setUp() {
            super.setUp()
            
            addChildController(formController)
        }
        
        override func cleanContent() {
            super.cleanContent()
            
            formController.removeFromParentViewController()
        }
        
        private func setSections() {
            formController.sections.append([
            //add items to child controller
            ])
        }
    }
    
    1 回复  |  直到 3 年前
        1
  •  0
  •   matt    3 年前

    问题是:

    public private(set) lazy var formController: ChildController = {
        let controller = FormTableView_Controller(style: .insetGrouped)
        return controller
    }()
    

    删除它。父级和子级都不能存储对另一个的引用。如果他们需要谈论彼此,则子级必须只谈论父级视图控制器,而父级则必须只谈论其子级,使用 parent children UIViewController类中已经提供了引用。