In HMSegmentedControl
, I'd like to set the segmentedControl.indexChangeBlock
to an instance method to handle the action.
The official example is: https://github.com/HeshamMegid/HMSegmentedControl/blob/master/HMSegmentedControlExample/HMSegmentedControlExample/ViewController.m (Line 63 ~ 68), but that's Objective-C.
In Swift, functions are first class citizens. So I wanna set an instance method to this block property.
But my code would lead to a circular reference, it seems that I should define a weak reference:
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
}
}
However, I cannot define a weak reference to a non-class type. What can I do? Is it legal to do this?
[unowned self]
is dangerous. What this does is to tell the runtime 'Assume self has not been released, don't worry about checking.' If self
does get released in the meantime, your application will SEGFAULT.
In this case, { [weak self] in self?.someInstanceMethod($0) }
will break the reference cycle, and turns into a no-op
if self
is released.
[weak self]
is always safe, while [unowned self]
can introduce app crashes if you modify other areas of your code (like view hierarchy, for example)...
Instead of defining weak reference to the closure, you should use "Capture List" in the closure.
segmentedControl3.indexChangeBlock = { [unowned self] in self.someInstanceMethod($0) }
As far as I know, this is the only way to avoid strong reference cycles.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With