ios – UIkit: Potential Retain Cycle Between UIInputView and _UIInputViewContent

0
1
ios – UIkit: Potential Retain Cycle Between UIInputView and _UIInputViewContent


I’m experiencing reminiscence leaks in my iOS app that appear to be associated to a problem between UIInputView and _UIInputViewContent. After utilizing the reminiscence graph, I am seeing that cases of those objects aren’t being deallocated correctly.

UIInputView and _UIInputViewContent referencing one another strongly

The UIInputViewController whichs holds the inputView is being deallocated correctly together with its subviews.I’ve tried to take away all of UIInputViewController’s subviews and their capabilities however the uiInputView is just not being deallocated.

The present setup of my app is a collectionView with a number of cell,every possessing a textfield with holds a UIInputViewController.When i scroll up or down,the views are being reused as anticipated and the variety of UIInputViewController stays per the variety of textfields.Nevertheless the variety of inputView retains rising referencing solely _UIInputViewContent.

class KeyboardViewController: UIInputViewController {
    
    // Callbacks
    var key1: ((String) -> Void)?
    var key2: (() -> Void)?
    var key3: (() -> Void)?
    var key4: (() -> Void)?
    
    non-public lazy var buttonTitles = [
        ["1", "2", "3"],
        ["4", "5", "6"],
        ["7", "8", "9"]
    ]
    
    override func viewDidLoad() {
        tremendous.viewDidLoad()
        setupKeyboard()
    }
    
    lazy var mainStackView: UIStackView = {
        let mainStackView = UIStackView()
        mainStackView.axis = .vertical
        mainStackView.distribution = .fillEqually
        mainStackView.spacing = 16
        mainStackView.translatesAutoresizingMaskIntoConstraints = false
        return mainStackView
    }()
    
    
    non-public func setupKeyboard() {
        let keyboardView = UIView(body:CGRect(x: 0, y: 0, width: UIScreen.important.bounds.width, peak: 279.0))
        
        keyboardView.addSubview(mainStackView)
        
        NSLayoutConstraint.activate([
            mainStackView.topAnchor.constraint(equalTo: keyboardView.topAnchor, constant: 16),
            mainStackView.leadingAnchor.constraint(equalTo: keyboardView.leadingAnchor, constant: 0),
            mainStackView.trailingAnchor.constraint(equalTo: keyboardView.trailingAnchor, constant: -24),
            mainStackView.bottomAnchor.constraint(equalTo: keyboardView.bottomAnchor, constant: -35)
        ])
        
        // Create rows
        for (_, _) in buttonTitles.enumerated() {
            let rowStackView = UIStackView()
            
            rowStackView.axis = .horizontal
            rowStackView.distribution = .fillEqually
            rowStackView.spacing = 1
            
//             Create buttons for every row
            for title in rowTitles {
                let button = createButton(title: title)
                rowStackView.addArrangedSubview(button)
            }
            
            mainStackView.addArrangedSubview(rowStackView)
        }
        self.view = keyboardView
    }
    
    non-public func createButton(title: String) -> UIButton {
        swap title {
            ///returns a uibutton primarily based on title
        }
    }
    
    // MARK: - Button Actions
    @objc non-public func numberTapped(_ sender: UIButton) {
        if let quantity = sender.title(for: .regular) {
            key1?(quantity)
        }
    }
    
    @objc non-public func key2Called() {
        key2?()
    }

    @objc non-public func key3Called() {
        key3?()
    }

    @objc non-public func key4Called() {
        key4?()
    }
    
    deinit {
        // Clear any sturdy references
        key1 = nil
        key2 = nil
        key3 = nil
        key4 = nil
        
        for subview in mainStackView.arrangedSubviews {
            if let stackView = subview as? UIStackView {
                for button in stackView.arrangedSubviews {
                    (button as? UIButton)?.removeTarget(self, motion: nil, for: .allEvents)
                }
            }
        }
        mainStackView.removeFromSuperview()
    }
}

Surroundings

iOS 16.3
Xcode 18.3.1

Any insights can be tremendously appreciated as that is inflicting noticeable reminiscence development in my app over time.

LEAVE A REPLY

Please enter your comment!
Please enter your name here