I want to add closure properties in the extension of UITextView
so I define a closure using typealias:
typealias TextViewHeightDidChangedClosure = (_ currentTextViewHeight:CGFloat)->Void
extension UITextView{
func setTextViewHeightDidChanged(textViewHeightDidChanged:TextViewHeightDidChangedBlock){
objc_setAssociatedObject(self, &TextViewHeightDidChangedBlockKey, textViewHeightDidChanged, objc_AssociationPolicy.OBJC_ASSOCIATION_COPY_NONATOMIC)
}
func textViewHeightDidChanged()->TextViewHeightDidChangedBlock?{
let textChanged : ((CGFloat)->Void) = objc_getAssociatedObject(self, &TextViewHeightDidChangedBlockKey) as! TextViewHeightDidChangedBlock
return textChanged
}
}
But it tells me an error that says:
Command failed due to signal: Segmentation fault: 11.
Here is an image of the error
Can anyone tell me why and give me an deep meaningful explanation, thank you very much!
You can also have this error if you declare a Bool!
property in a class and you try to make a ternary condition with this property:
var isSomething: Bool!
func myFunc() {
let value = isSomething ? "something" : "not"
}
Just add the ! on your property
var isSomething: Bool!
func myFunc() {
let value = isSomething! ? "something" : "not"
}
Generally, crashing with SegFault 11 is a bug of compiler and you'd better send a bug report.
And most such bugs can be worked around with fixing your code properly.
The most significantly bad thing in your code is that usual closures in Swift (@convention(swift)
-- usually omitted) cannot be passed to Any
which represents id
of Objective-C. Use @convention(block)
which is stated as id
-compatible in the Swift book (this part):
typealias TextViewHeightDidChangedBlock = @convention(block) (_ currentTextViewHeight:CGFloat)->Void
You may have tried this, but in this case, just putting @convention(block)
does not solve the issue.
It seems another trick is needed to make your code work, explicitly cast to AnyObject
:
extension UITextView{
func setTextViewHeightDidChanged(textViewHeightDidChanged: @escaping TextViewHeightDidChangedBlock){
objc_setAssociatedObject(self, &TextViewHeightDidChangedBlockKey, textViewHeightDidChanged as! AnyObject, objc_AssociationPolicy.OBJC_ASSOCIATION_COPY_NONATOMIC)
}
func textViewHeightDidChanged()->TextViewHeightDidChangedBlock?{
let textChanged : ((CGFloat)->Void) = objc_getAssociatedObject(self, &TextViewHeightDidChangedBlockKey) as! TextViewHeightDidChangedBlock
return textChanged
}
}
So, this seems to be a flaw of id-as-Any
. Any
which represents id
should accept id
-compatible closure.
I'm not sure Apple would fix this bug soon, but anyway, as far as I tested, my code above worked as expected.
For me it was because I was declaring protocols for two extensions on a generic class and implementing them in the class declaration. I am using xCode 9 swift 4
I faced the similar issue in Xcode 9.3, I opened the given swift class as mentioned in error image(mine was differ), went to method(mention in error) there was code like below
class func makeViewCircular(view: AnyObject) {
let viewCircle = view
viewCircle.layer.cornerRadius = view.frame.size.width/2
viewCircle.layer.borderColor = UIColor.clear.cgColor
viewCircle.layer.borderWidth = 1.0
}
So, I edit the code to like below. Fixed the problem. The problem was with the AnyObject type. I typecast AnyObject to UIView.
class func makeViewCircular(view: AnyObject) {
if let viewCircle = view as? UIView{
viewCircle.layer.cornerRadius = view.frame.size.width/2
viewCircle.layer.borderColor = UIColor.clear.cgColor
viewCircle.layer.borderWidth = 1.0
}
}