"self as?" within protocol extension

532 views Asked by At

I was trying for casting "self" within protocol extension. It crashed with EXC_BAD_ACCESS error when running on real device but worked well on simulator. What should I do to make this work? Thanks

My whole code:

protocol SomeProtocol: class {

}

protocol DataSetEditable {
    func add(_ data: Data)
}

extension DataSetEditable where Self: SomeClass {
    func add(_ data: Data) {
        print(data)
        if let someProtocol = self as? SomeProtocol {
            print(someProtocol)
            //do some extra works
        }
    }
}

class SomeClass: UIView {

}

class MyClass: SomeClass, DataSetEditable, SomeProtocol {
}

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let myClass = MyClass()
        myClass.add(Data())
    }
}
2

There are 2 answers

1
Rob Napier On BEST ANSWER

First, this is likely a Swift bug since the compiler should have provided an error if it can't handle this. You should open it at bugs.swift.com. This feels related to SR-544.

That said, as a rule it is very tricky to conform ObjC types to Swift-only protocols. Sometimes it works, sometimes it doesn't. This is a pretty complicated conformance, and clearly it doesn't always work. The solution is to expose the protocol to ObjC by adding @objc:

@objc protocol SomeProtocol: class {}
1
Ratnesh Jain On

You can try to extend the DataSetEditable like below.

extension DataSetEditable where Self: SomeClass & SomeProtocol {
  func add(_ data: Data) {
   ...
  }
}

Now the above extension method func add(_ data: Data) only accessible to the subclass of SomeClass and follows SomeProtocol.