UIkit ChildController 保留循环

huangapple go评论62阅读模式
英文:

UIkit ChildController Retain Cycle

问题

你好,以下是您要翻译的内容:

"Hi I am making an app where I use a tableView like Apples Settings app. I use this tableview in various controllers, so I made a controller that is added as a child to the controllers that require the use of this tableview.

The reason it is a child controller is because it needed the layout and functionality of the table to be used repeatedly in multiple controllers.

The problem I'm having is adding a child controller keeps the controller retained in memory.

Here's how to remove the child before the main controller disappears:

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

This is how I add the child to the main controller:

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

Child controller:

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...
}

Main Controller:

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
        ])
    }
}

希望对您有所帮助!

英文:

Hi I am making an app where I use a tableView like Apples Settings app. I use this tableview in various controllers, so I made a controller that is added as a child to the controllers that require the use of this tableview.

The reason it is a child controller is because it needed the layout and functionality of the table to be used repeatedly in multiple controllers.

The problem I'm having is adding a child controller keeps the controller retained in memory.

Here's how to remove the child before the main controller disappears:

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

This is how I add the child to the main controller:

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

Child controller:

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...
}

Main Controller:

 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

得分: 0

以下是翻译好的部分:

"Delete that. Neither parent nor child must have a stored reference to the other. If they need to speak of one another at all, the child must speak only of the parent view controller and the parent must speak only of its children, using the parent and children references already provided in the UIViewController class."

不要有别的内容。

英文:

Here's the problem:

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

Delete that. Neither parent nor child must have a stored reference to the other. If they need to speak of one another at all, the child must speak only of the parent view controller and the parent must speak only of its children, using the parent and children references already provided in the UIViewController class.

huangapple
  • 本文由 发表于 2023年5月28日 09:16:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76349604.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定