如何在Swift中设置对闭包/函数的弱引用?

Wil*_*Cat 14 closures ios swift

HMSegmentedControl,我想设置segmentedControl.indexChangeBlock一个实例方法来处理动作.官方的例子是:https://github.com/HeshamMegid/HMSegmentedControl/blob/master/HMSegmentedControlExample/HMSegmentedControlExample/ViewController.m(第63~68行),但这是Objective-C.

在斯威夫特,功能是一等公民.所以我想为这个块属性设置一个实例方法.
但是我的代码会导致循环引用,似乎我应该定义一个弱引用:

class ExampleVC: UIViewController {
    var segmentedControlIndex: Int = 0

    override func viewDidLoad() {
      let segmentedControl3 = HMSegmentedControl(sectionImages: ... , sectionSelectedImages: ... )
      segmentedControl3.frame = ...
      segmentedControl3.indexChangeBlock = someInstanceMethod
    }

    func someInstanceMethod(index: Int) {
      segmentedControlIndex = index
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,我无法定义对非类类型的弱引用.我能做什么?这样做是否合法?

And*_*ken 20

[unowned self]很危险 这样做是为了告诉运行时'假设自己还没有被释放,不用担心检查.' 如果self在此期间发布,您的应用程序将为SEGFAULT.

在这种情况下,{ [weak self] in self?.someInstanceMethod($0) }将打破参考循环,并变为no-opif self释放.

[weak self]总是安全的,[unowned self]如果您修改代码的其他区域(例如视图层次结构),可能会引入应用程序崩溃...


rin*_*aro 7

您应该在闭包中使用"捕获列表",而不是定义对闭包的弱引用.

segmentedControl3.indexChangeBlock = { [unowned self] in self.someInstanceMethod($0) }
Run Code Online (Sandbox Code Playgroud)

据我所知,这是避免强参考周期的唯一方法.

  • `[weak self]`将破坏引用循环,并且在代码被重构或视图层次结构重组时通常不易破损. (6认同)