Skip to content

Instantly share code, notes, and snippets.

@dafurman
Forked from macabeus/listClasses.swift
Created November 13, 2023 23:21
Show Gist options
  • Select an option

  • Save dafurman/f47bef4b19187035e4fde035ef536620 to your computer and use it in GitHub Desktop.

Select an option

Save dafurman/f47bef4b19187035e4fde035ef536620 to your computer and use it in GitHub Desktop.

Revisions

  1. brunomacabeusbr revised this gist Mar 21, 2017. 1 changed file with 3 additions and 4 deletions.
    7 changes: 3 additions & 4 deletions listClasses.swift
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,4 @@
    // Many thanks to Code Different: http://stackoverflow.com/a/42749141/3440266

    import Foundation

    struct ClassInfo : CustomStringConvertible, Equatable {
    @@ -63,7 +62,7 @@ print(listSubclasses)

    ////
    // List classes that subscribers a protocol
    func subscribers(cond: (AnyObject) -> Any?) -> [ClassInfo] {
    func subscribers<T>(of: T.Type) -> [ClassInfo] {
    var subscribersList = [ClassInfo]()

    var count = UInt32(0)
    @@ -78,7 +77,7 @@ func subscribers(cond: (AnyObject) -> Any?) -> [ClassInfo] {
    }

    //
    if cond(classInfo.classObject) != nil {
    if classInfo.classObject is T {
    subscribersList.append(classInfo)
    }
    }
    @@ -95,5 +94,5 @@ class Bar: Proto, Proto2 { }
    class Baz: Proto2 { }
    class Qux { }

    let listProto = subscribers(cond: { $0 as? Proto.Type } )
    let listProto = subscribers(of: Proto.Type.self )
    print(listProto)
  2. brunomacabeusbr revised this gist Mar 14, 2017. 2 changed files with 99 additions and 59 deletions.
    99 changes: 99 additions & 0 deletions listClasses.swift
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,99 @@
    // Many thanks to Code Different: http://stackoverflow.com/a/42749141/3440266

    import Foundation

    struct ClassInfo : CustomStringConvertible, Equatable {
    let classObject: AnyClass
    let classNameFull: String
    let className: String

    init?(_ classObject: AnyClass?) {
    guard classObject != nil else { return nil }

    self.classObject = classObject!

    let cName = class_getName(classObject)!
    self.classNameFull = String(cString: cName)
    self.className = self.classNameFull.components(separatedBy: ".").last!
    }

    var superclassInfo: ClassInfo? {
    let superclassObject: AnyClass? = class_getSuperclass(self.classObject)
    return ClassInfo(superclassObject)
    }

    var description: String {
    return self.classNameFull
    }

    static func ==(lhs: ClassInfo, rhs: ClassInfo) -> Bool {
    return lhs.classNameFull == rhs.classNameFull
    }
    }

    ////
    // List classes that are subclasses
    func subclasses(of classMother: AnyClass) -> [ClassInfo] {
    let motherClassInfo = ClassInfo(classMother.self)!
    var subclassesList = [ClassInfo]()

    var count = UInt32(0)
    let classList = objc_copyClassList(&count)!

    for i in 0..<Int(count) {
    if let classInfo = ClassInfo(classList[i]),
    let superclassInfo = classInfo.superclassInfo,
    superclassInfo == motherClassInfo
    {
    subclassesList.append(classInfo)
    }
    }

    return subclassesList
    }

    // Example
    class Mother { }
    class Brother: Mother { }
    class Sister: Mother { }
    class Cousin { }

    let listSubclasses = subclasses(of: Mother.self)
    print(listSubclasses)

    ////
    // List classes that subscribers a protocol
    func subscribers(cond: (AnyObject) -> Any?) -> [ClassInfo] {
    var subscribersList = [ClassInfo]()

    var count = UInt32(0)
    let classList = objc_copyClassList(&count)!

    for i in 0..<Int(count) {
    if let classInfo = ClassInfo(classList[i]) {

    // skip native Swift and Foundation classes, to do not crash
    if classInfo.classNameFull.components(separatedBy: ".").count == 1 {
    continue
    }

    //
    if cond(classInfo.classObject) != nil {
    subscribersList.append(classInfo)
    }
    }
    }

    return subscribersList
    }

    // Example
    protocol Proto { }
    protocol Proto2 { }
    class Foo: Proto { }
    class Bar: Proto, Proto2 { }
    class Baz: Proto2 { }
    class Qux { }

    let listProto = subscribers(cond: { $0 as? Proto.Type } )
    print(listProto)
    59 changes: 0 additions & 59 deletions subscribers.swift
    Original file line number Diff line number Diff line change
    @@ -1,59 +0,0 @@
    // Inspired by Code Different's code at http://stackoverflow.com/a/42749141/3440266
    import Foundation

    struct ClassInfo: CustomStringConvertible, Equatable {
    let classObject: AnyClass
    let className: String
    let classNameCroped: String

    init?(_ classObject: AnyClass?) {
    guard classObject != nil else { return nil }

    self.classObject = classObject!

    let cName = class_getName(classObject)!
    self.className = String(cString: cName)
    self.classNameCroped = self.className.components(separatedBy: ".").last!
    }

    var superclassInfo: ClassInfo? {
    let superclassObject: AnyClass? = class_getSuperclass(self.classObject)
    return ClassInfo(superclassObject)
    }

    var description: String {
    return self.className
    }

    static func ==(lhs: ClassInfo, rhs: ClassInfo) -> Bool {
    return lhs.className == rhs.className
    }
    }

    fileprivate var count = UInt32(0)
    fileprivate let classList = objc_copyClassList(&count)!

    //
    protocol Proto { }
    class Foo: Proto { }
    class Bar: Proto { }
    class Baz { }

    //
    func subscribersOfProto() -> [ClassInfo] { // TODO: Pass a protocol as parameter, without using @objc
    var subscribersList = [ClassInfo]()

    for i in 0..<Int(count) {
    if let classInfo = ClassInfo(classList[i]) {

    if let _ = classInfo.classObject as? Proto.Type {
    subscribersList.append(classInfo)
    }
    }
    }

    return subscribersList
    }

    let list = subscribersOfProto()
    print(list) // [subscribers.Bar, subscribers.Foo]
  3. brunomacabeusbr revised this gist Mar 13, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion subscribers.swift
    Original file line number Diff line number Diff line change
    @@ -56,4 +56,4 @@ func subscribersOfProto() -> [ClassInfo] { // TODO: Pass a protocol as parameter
    }

    let list = subscribersOfProto()
    print(list) // [subscribes.Bar, subscribes.Foo]
    print(list) // [subscribers.Bar, subscribers.Foo]
  4. brunomacabeusbr revised this gist Mar 13, 2017. No changes.
  5. brunomacabeusbr revised this gist Mar 13, 2017. No changes.
  6. brunomacabeusbr renamed this gist Mar 13, 2017. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  7. brunomacabeusbr created this gist Mar 13, 2017.
    59 changes: 59 additions & 0 deletions subscribes.swift
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,59 @@
    // Inspired by Code Different's code at http://stackoverflow.com/a/42749141/3440266
    import Foundation

    struct ClassInfo: CustomStringConvertible, Equatable {
    let classObject: AnyClass
    let className: String
    let classNameCroped: String

    init?(_ classObject: AnyClass?) {
    guard classObject != nil else { return nil }

    self.classObject = classObject!

    let cName = class_getName(classObject)!
    self.className = String(cString: cName)
    self.classNameCroped = self.className.components(separatedBy: ".").last!
    }

    var superclassInfo: ClassInfo? {
    let superclassObject: AnyClass? = class_getSuperclass(self.classObject)
    return ClassInfo(superclassObject)
    }

    var description: String {
    return self.className
    }

    static func ==(lhs: ClassInfo, rhs: ClassInfo) -> Bool {
    return lhs.className == rhs.className
    }
    }

    fileprivate var count = UInt32(0)
    fileprivate let classList = objc_copyClassList(&count)!

    //
    protocol Proto { }
    class Foo: Proto { }
    class Bar: Proto { }
    class Baz { }

    //
    func subscribersOfProto() -> [ClassInfo] { // TODO: Pass a protocol as parameter, without using @objc
    var subscribersList = [ClassInfo]()

    for i in 0..<Int(count) {
    if let classInfo = ClassInfo(classList[i]) {

    if let _ = classInfo.classObject as? Proto.Type {
    subscribersList.append(classInfo)
    }
    }
    }

    return subscribersList
    }

    let list = subscribersOfProto()
    print(list) // [subscribes.Bar, subscribes.Foo]