前言
對于OC來說可以動态擷取類的屬性、方法等資訊,但是對于Swift來說能不能擷取到呢,我們先來看個實驗。
實驗
首先定義個純Swift類,沒有繼承NSObject。
class PersonModel {
var name = "張三";
var age = 18;
func printInfo() -> Void {
print("姓名:\(name)\n年齡:\(age)");
}
}
上邊定義了簡單的PersonModel類,沒有繼承任何類,那麼我們通過runtime看看是否可以擷取這個類的屬性麼。
測試案例:
let model = PersonModel();
var count: UInt32 = 0;
let cls = object_getClass(model);
let plist = class_copyPropertyList(cls, &count);
print("===開始擷取");
for item in 0..<count {
let property = plist?[Int(item)]
let cname = property_getName(property!);
let name = String(cString: cname);
print("property:<\(name)>")
}
print("===結束擷取");
下圖是輸出結果:

可以看到沒有擷取到任何屬性。
那麼我們就可以得出結論,純Swift在runtime是沒有辦法擷取類的屬性的。那麼擷取類的方法呢,我們再看下面的測試。
代碼接着測試:
print("===開始擷取");
let methodList = class_copyMethodList(cls, &count);
for item in 0..<count {
let meth = methodList![Int(item)];
let m = method_getName(meth);
let mStrl = NSStringFromSelector(m);
print("方法:\(mStrl)");
}
print("===結束擷取");
同樣沒有擷取任何函數, 純swift在runtime運作的時候是沒有辦法擷取函數的。
由此可以推論出,純swift在runtime運作的時候是沒有辦法擷取到類任何資訊。也可以看出swift并不支援動态擷取資訊。
那麼我們就真的沒有辦法擷取類的屬性了麼?我們知道swift是可以和OC混合開發的,也就是swift也支援OC,但是OC确實動态語言,是以swift也會不會繼承OC的特性呢。我們趕緊測試一下。
我們先改一下這個PersonModel類。讓他繼承NSObject類。如下:
class PersonModel : NSObject{
var name = "張三";
var age = 18;
func printInfo() -> Void {
print("姓名:\(name)\n年齡:\(age)");
}
}
我們在運作一邊上邊的測試案例;會發現一個并沒有擷取到自己定義的任何資訊,現在是用swift 4.2版本測試的,這個因為swift 4.2版本已經把@objc 去掉了,繼承NSObject的類不會再自動生成@objc 的特性了,需要我們手動添加,這個@objc 是幹什麼的呢,添加這個是表明改屬性具有OC屬性的特性。那麼我們加上以後,會看到如下的輸出:
這個輸出結果看着是不是很像OC的方法。對,就是,加了@objc 就會預設生成OC的get、set方法。還有兩個函數init、.cxx_destruct這兩個函數,以後再說。先不用管。
通過以上測試我們可以看到,繼承NSObject添加的@objc 我們才可以擷取到類的屬性和方法。
結論:
純Swift是在編譯的時候已經确定了要調用的方法,而不是在運作的時候确定,這個和C有點類似,是以我們是沒有辦法在運作時擷取方法和屬性的。
對于繼承OC的swift,并且有@objc 特性,才會保留OC運作時的特性。我們才可以在運作時候擷取他們的屬性和方法。