Swift

Swift 인스턴스 method 목록 가져오는 방법

Phililip
728x90

Objecitve-C는 runtime.h를 사용하면 인스턴스 method 목록을 가져올 수 있지만

Swift는 쉽지 않더라구요...

Swift에서 인스턴스 method 목록을 가져올 수 있는 꼼수(?)를 발견해서 내용을 정리합니다.

#1 제약조건

Swift 클래스는 NSObject를 상속 받아야 합니다..ㅠㅠ
@objc 태그가 붙은 method 정보만 가져올 수 있습니다...ㅠㅠ
static method 정보는 읽어올 수 없습니다...ㅠㅠ

#2 extension 추가

NSObject를 extension한 아래 코드를 추가해주세요.

extension NSObject {
    static func methodList(className: String) -> [String]? {
        guard let someClass = NSClassFromString(className) else { return nil }
        return self.methodList(cls: someClass)
    }

    static func methodList(cls: AnyClass) -> [String]? {
        var methodCount: UInt32 = 0
        let methodList = class_copyMethodList(cls, &methodCount)

        var result = [String]()

        if let methodList = methodList, methodCount > 0 {
            enumerateCArray(array: methodList, count: methodCount) { i, m in
                let name = methodName(m: m) ?? "unknown"
                result.append(name)
            }
            free(methodList)
        }

        return result
    }
}

private extension NSObject {
    static func enumerateCArray<T>(array: UnsafePointer<T>, count: UInt32, f: (UInt32, T) -> Void) {
        var ptr = array
        for i in 0..<count {
            f(i, ptr.pointee)
            ptr = ptr.successor()
        }
    }

    static func methodName(m: Method) -> String? {
        let sel = method_getName(m)
        let nameCString = sel_getName(sel)
        return String(cString: nameCString)
    }
}

#3 사용방법

NSObject를 상속받은 class를 생성해주시고,

class MyClass: NSObject {
    @objc public func publicFunc() {
        // ...
    }

    @objc private func privateFunc() {
        // ...
    }
}

위에서 extension으로 구현한 methodList를 호출하면 method 목록을 가져올 수 있습니다.

let className: String = NSStringFromClass(type(of: MyClass()))
let methodList: [String]? = NSObject.methodList(className: className)
print(methodList)     // ["publicFunc", "privateFunc", "init"]
반응형

'Swift' 카테고리의 다른 글

CryptoKit을 사용한 암호화  (0) 2022.02.23
async/await 용 public API를 추가할 때 고려사항  (1) 2022.02.23
Core Data의 not Optional 설정 시 크래쉬 주의  (0) 2022.02.20
enum 남용 주의  (0) 2022.02.17
Literal 이란?  (1) 2022.02.07