0

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())
    }
}
Cuong Nguyen
  • 376
  • 1
  • 5
  • 8

2 Answers2

1

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.

Ratnesh Jain
  • 671
  • 7
  • 14
  • I cannot do that because I have AnotherClass which is a child of SomeClass and not conforming SomeProtocol protocol. So that AnotherClass cannot use add(_ data: Data) function and it has to implement add(_ data: Data) by itself. – Cuong Nguyen Apr 17 '18 at 10:23
1

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 {}
Rob Napier
  • 286,113
  • 34
  • 456
  • 610