Development wants to know how many classes a protocol is implemented by. There’s no way to know.

protocol Animal {
    func speak(a)
}

class Cat:Animal {
    func speak(a) {
        print("meow")}}class Dog: Animal {
    func speak(a) {
        print("An An!")}}class Horse: Animal {
    func speak(a) {
        print("Hurrrr")}}Copy the code

You can find these on the Internet

  • objc_copyProtocolList// Get all the protocols known by the runtime
  • protocol_copyProtocolList// Returns an array of the protocols used by the protocol.

The above two methods, one is to know how many protocol array, one is to know the protocol array used by the protocol. They have no way of knowing how many classes a protocol is implemented by. It didn’t work. You need to be flexible. Instead, find these two methods

  • objc_getClassList// Get all the classes that the runtime knows about
  • class_conformsToProtocol// Get whether a class implements a protocol.

With these two methods, you can get all the classes and then iterate over whether each class implements the target protocol. The code is as follows:

func getClassesConformingProtocol(a)- > {let expectedClassCount = objc_getClassList(nil.0)
        let allClasses = UnsafeMutablePointer<AnyClass>.allocate(capacity: Int(expectedClassCount))
        let autoreleasingAllClasses = AutoreleasingUnsafeMutablePointer<AnyClass>(allClasses)
        let actualClassCount:Int32 = objc_getClassList(autoreleasingAllClasses, expectedClassCount)

        for i in 0 ..< actualClassCount {
            let currentClass = allClasses[Int(i)]
            if class_conformsToProtocol(currentClass, Animal.Type) {
                print(currentClass)
            }
        }
}
Copy the code

The problem is that class_conformsToProtocol always fails in Swift.

Then work around, because we know that in swift we can determine whether aclass complies with a protocol by (aclass as? Aprotocol). The code is modified as follows:

func getClassesConformingProtocol(a)- > {let expectedClassCount = objc_getClassList(nil.0)
        let allClasses = UnsafeMutablePointer<AnyClass>.allocate(capacity: Int(expectedClassCount))
        let autoreleasingAllClasses = AutoreleasingUnsafeMutablePointer<AnyClass>(allClasses)
        let actualClassCount:Int32 = objc_getClassList(autoreleasingAllClasses, expectedClassCount)

        for i in 0 ..< actualClassCount {
            let currentClass = allClasses[Int(i)]
            if let cls = currentClass as? Animal.Type {
                print(currentClass)
            }
        }
}

Copy the code

A goal

This error occurs when this part of the code is called by OC.

 * * * NSForwarding: warning: object 0x10bec81d0 of class 'Object' does not implement methodSignatureForSelector: -trouble ahead* * *NSForwarding: warning: object 0x10bec81d0 of class 'Object' does not implement doesNotRecognizeSelector: -abort
Copy the code

The solution is simple

func getClassesConformingProtocol(a)- > {let expectedClassCount = objc_getClassList(nil.0)
        let allClasses = UnsafeMutablePointer<AnyClass>.allocate(capacity: Int(expectedClassCount))
        let autoreleasingAllClasses = AutoreleasingUnsafeMutablePointer<AnyClass>(allClasses)
        let actualClassCount:Int32 = objc_getClassList(autoreleasingAllClasses, expectedClassCount)

        for i in 0 ..< actualClassCount {
            let currentClass = allClasses[Int(i)]
            if (class_getInstanceMethod(currentClass, NSSelectorFromString("methodSignatureForSelector:")) ! = nil),

               (class_getInstanceMethod(currentClass, NSSelectorFromString("doesNotRecognizeSelector:")) ! = nil),
               let cls = currentClass as? Animal.Type {
                print(currentClass)
            }
        }
}
Copy the code

Reference: stackoverflow.com/questions/3…