Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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

>Solution :

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading