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 |