RuntimeAPIを使った実装について書いていきます。
Swiftでプロパティー一覧を取得する
下のようなコードでプロパティー名を取得できます。
class_copyPropertyListでプロパティー情報が取得できるので、property_getNameを使ってプロパティーの名前を取得します。
class MyClass: NSObject {
var prop1 = ""
var prop2 = ""
}
var count: UInt32 = 0
let properties = class_copyPropertyList(MyClass.self, &count)
for i in 0..<Int(count) {
let prop = properties[i]
let propName = NSString(UTF8String: property_getName(prop))
}
取得できるプロパティーの条件
上記方法でも常にプロパティーが取れるわけではありません。
取得できるプロパティーは「そのクラスがNSObjectのサブクラス」「プロパティーにdynamicか@objcが付いている」のどちらかを満たした物だけです。
class MyClass {
dynamic var prop1 = "" // これは取得できる
var prop2 = ""
}
privateなプロパティーも取得できませんでした。
class MyClass: NSObject {
private var prop1 = "" // これは取得できない
var prop2 = ""
}
文字列を使ってプロパティーを呼び出す
NSObjectを継承している場合はvalueForKeyを使えばメソッド名を使ったプロパティー呼び出しができます。
class MyClass: NSObject {
var prop = ""
}
let myClass = MyClass()
myClass.prop = "PROP!!"
print(myClass.valueForKey("prop")) // → PROP!!
class_copyIvarListを使ってプロパティー一覧を取得する
class_copyIvarListでもclass_copyPropertyListと同じようにプロパティー一覧を取得できました。
class_copyPropertyListと違ってclass_copyIvarListではprivateなプロパティーも取得する事ができました。
class MyClass: NSObject {
private var prop1 = "" // これも取れた
var prop2 = ""
}
let ivar = class_copyIvarList(MyClass.self, &count)
for i in 0..<Int(count) {
let prop = ivar[i]
print(NSString(UTF8String: ivar_getName(prop)))
}