Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

List all subclasses of one class

Can I return a list of all subclasses of one class? For example:

class Mother {

}

class ChildFoo: Mother {

}

class ChildBar: Mother {

}

let motherSubclasses = ... // TODO
print(motherSubclasses) // should to return [ChildFoo.self, ChildBar.self]
like image 654
macabeus Avatar asked Mar 12 '17 11:03

macabeus


People also ask

How do you get all the subclasses of sealed classes?

Getting Subclasses of a Sealed Class As we know, sealed classes and interfaces are inheritance hierarchies with a simple restriction: Only classes and interfaces in the same package can extend them. Therefore, all the subclasses of a particular sealed class are known at compile-time.

What is a subclass in Python?

What is Subclass? A class that is derived from another class is known as a subclass. This is a concept of inheritance in Python. The subclass derives or inherits the properties of another class. Since Python classes are first-class objects, "given its name" signifies that you do not need to use a string with the class's name in place of the class.

What is the default sorting for class/subclass articles?

The default sorting is the order in which the class or subclass was released. The links to articles on each character class or subclass refer to the class or subclass in general, rather than just the D&D 5th edition incarnation.

What are the different subclasses of Warlock?

Subclasses Subclass Class Clockwork Soul Sorcerer The Fathomless Warlock The Genie Warlock Order of Scribes Wizard 31 more rows ...


1 Answers

An optimised version of Jean Le Moignan's code

    static func subclasses<T>(of theClass: T) -> [T] {
        var count: UInt32 = 0, result: [T] = []
        let allClasses = objc_copyClassList(&count)!
        let classPtr = address(of: theClass)

        for n in 0 ..< count {
            let someClass: AnyClass = allClasses[Int(n)]
            guard let someSuperClass = class_getSuperclass(someClass), address(of: someSuperClass) == classPtr else { continue }
            result.append(someClass as! T)
        }

        return result
    }
public func address(of object: Any?) -> UnsafeMutableRawPointer{
    return Unmanaged.passUnretained(object as AnyObject).toOpaque()
}

For every Type there is only one metaclass instance in runtime, so, pointers on them are unique. In some reason operator === is not allowed for AnyClass, but we can compare pointers directly

performance test:

        let start = CFAbsoluteTimeGetCurrent()
        let found = RuntimeUtils.subclasses(of:UIViewController.self)
        let diff = CFAbsoluteTimeGetCurrent() - start
        print("Took \(diff) seconds, \(found.count) found")

output:

String(describing: theClass): Took 1.0465459823608398 seconds, 174 found

address(of: theClass): Took 0.2642860412597656 seconds, 174 found

like image 145
Krypt Avatar answered Sep 23 '22 18:09

Krypt