最近寫swift的時候,用到了一些運行時的東西,但是有部分與oc還是有差異的,得不到想要的東西,於是記錄一下目前自己遇到的兩者之間的差別。
ivar_getTypeEncoding
在swift中,我用這個函數,就是得不到一個對象屬性的類型。
首先定義了一個Person類作爲測試
/******************這是swift*********************/
class Person: NSObject {
var name = "123"
var age = 18
var color = UIColor.white
}
var count: UInt32 = 0
let ivars = class_copyIvarList(Person.self, &count)
for i in 0..<Int(count) {
let ivar = ivars![i]
let name = String(utf8String: ivar_getName(ivar)!)
let type = String(utf8String: ivar_getTypeEncoding(ivar)!)
print(name, type)
}
//輸出結果如下:swift中拿不到對象的屬性的類型。
Optional("name") Optional("")
Optional("age") Optional("")
Optional("color") Optional("")
/******************這是objective-c*********************/
@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) int age;
@property (nonatomic, strong) UIColor *color;
@end
unsigned int count = 0;
Ivar *ivars = class_copyIvarList([Person class], &count);
for (int i = 0; i < (int)count; i++) {
Ivar ivar = ivars[i];
const char *cName = ivar_getName(ivar);
const char *cType = ivar_getTypeEncoding(ivar);
NSString *name = [NSString stringWithUTF8String:cName];
NSString *type = [NSString stringWithUTF8String:cType];
NSLog(@"name = %@, type = %@", name, type);
}
//輸出結果如下:oc中是都可以拿到屬性的類型的。
name = _age, type = i
name = _name, type = @"NSString"
name = _color, type = @"UIColor"
可以看出,在swift中已經拿不到一個對象屬性的類型了。
object_setIvar
這個方法在swift中現在只有給類申明的變量設置值纔有效,其他的都無效。
/******************這是swift*********************/
class func modelWithDic(_ dic: [String: Any]) -> Any {
let obj = self.init()
for (key, value) in dic {
guard let ivar = class_getInstanceVariable(self, key) else {
continue
}
object_setIvar(obj, ivar, value)
}
return obj
}
let p = Person.modelWithDic(["name": "swift", "age": 25 ,"color": UIColor.blue]) as! Person
print(p.name, p.age, p.color)
//打印結果如下:可以看出,用String、Int定義的變量,設置的值是無效的,他們在swift中類型都是結構體,而用類定義的變量,設置的值是有效的。
\220r$ -5764607523034234477 UIExtendedSRGBColorSpace 0 0 1 1
/******************這是objective-c*********************/
+ (instancetype)modelWithDic:(NSDictionary *)dic {
id obj = [[self alloc] init];
[dic enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull value, BOOL * _Nonnull stop) {
NSString *ivarKey = [NSString stringWithFormat:@"_%@", key];
Ivar ivar = class_getInstanceVariable([self class], [ivarKey cStringUsingEncoding:NSUTF8StringEncoding]);
if (ivar != nil) {
object_setIvar(obj, ivar, value);
}
}];
return obj;
}
Person *p = [Person modelWithDic:@{@"name": @"oc", @"age": @10, @"color": [UIColor blueColor]}];
NSLog(@"name = %@, age = %d, color = %@", p.name, p.age, p.color);
//運行結果如下:可以看出,oc中是全部可以設置值的。
name = oc, age = 162, color = UIExtendedSRGBColorSpace 0 0 1 1