简体   繁体   中英

Use closure instead selector argument for UIBarButtonItem BUT without using weak self

In order to use closure in argument of UIBarButtonItem I am using a subclass:

class ActionBarButtonItem: UIBarButtonItem {
    private var actionHandler: (() -> Void)?

    convenience init(title: String?, style: UIBarButtonItemStyle, actionHandler: (() -> Void)?) {
        self.init(title: title, style: style, target: nil, action: #selector(barButtonItemPressed))
        self.target = self
        self.actionHandler = actionHandler
    }

    convenience init(image: UIImage?, style: UIBarButtonItemStyle, actionHandler: (() -> Void)?) {
        self.init(image: image, style: style, target: nil, action: #selector(barButtonItemPressed))
        self.target = self
        self.actionHandler = actionHandler
    }

    @objc func barButtonItemPressed(sender: UIBarButtonItem) {
        actionHandler?()
    }
}

but now I need to weak [weak self] :

    self.add(barButton: .menu, position: .left) { [weak self] in
        guard let strongSelf = self else {return}
        strongSelf.openMenu()
    }

is there a way to still use closure as selector but not save the closure to avoid using weak self everywhere and you may forget it somewhere ?

In a word, no.

You have to save the closure if you're going to call it later. If you're saving a closure, and that closure refers to self , you should make self part of a capture list to avoid a retain cycle. That's what capture lists are for, and is the correct coding pattern for this situation.

Any time you refer to self in a closure you need to stop and think about retain cycles.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM