protocol P: AnyObject { } class A: P {} Runtime.classes(conformTo: P.Type.self) // [MyApp.A] class Runtime { public static func allClasses() -> [AnyClass] { let numberOfClasses = Int(objc_getClassList(nil, 0)) if numberOfClasses > 0 { let classesPtr = UnsafeMutablePointer.allocate(capacity: numberOfClasses) let autoreleasingClasses = AutoreleasingUnsafeMutablePointer(classesPtr) let count = objc_getClassList(autoreleasingClasses, Int32(numberOfClasses)) assert(numberOfClasses == count) defer { classesPtr.deallocate() } let classes = (0 ..< numberOfClasses).map { classesPtr[$0] } return classes } return [] } public static func subclasses(of `class`: AnyClass) -> [AnyClass] { return self.allClasses().filter { var ancestor: AnyClass? = $0 while let type = ancestor { if ObjectIdentifier(type) == ObjectIdentifier(`class`) { return true } ancestor = class_getSuperclass(type) } return false } } public static func classes(conformToProtocol `protocol`: Protocol) -> [AnyClass] { let classes = self.allClasses().filter { aClass in var subject: AnyClass? = aClass while let aClass = subject { if class_conformsToProtocol(aClass, `protocol`) { print(String(describing: aClass)); return true } subject = class_getSuperclass(aClass) } return false } return classes } public static func classes(conformTo: T.Type) -> [AnyClass] { return self.allClasses().filter { $0 is T } } }