在swift中动态创建对象并设置属性

时间:2015-06-30 18:42:20

标签: ios swift

我正在研究一个自定义场景,其中我需要在运行时创建一个已定义类的对象,并为其设置属性。在Objective-C

中有类似的东西
//The Model class

@interface Car:NSObject
{
  @property(nonatomic,copy) NSString * numberOfDoors;
  @property(nonatomic,copy) NSString * carModel;
  @property(nonatomic,copy) NSString * carMake;
  @property(nonatomic,copy) NSString * carBrand;

}

为上面的类创建一个自定义运行时对象(不确定这是否正确,但只是从头顶说话)

id myNewObject =  [[NSClassFromString(@"Car") alloc]init];
[myNewObject setValue:@"4 doors" forKeyPath:@"numberOfDoors"];
[myNewObject setValue:@"Prius" forKeyPath:@"carModel"];
[myNewObject setValue:@"2014" forKeyPath:@"carMake"];
[myNewObject setValue:@"Toyota" forKeyPath:@"carBrand"];

所以我的目的是创建一个对象映射模块,它将获取类名和对象映射信息,这些信息将描述如何从JSON响应中映射/创建模型对象(与RestKit非常相似的东西减去核心数据同步部分)。

我知道这可以通过目标C完成,但不确定这将如何适用于swift类

感谢任何帮助。

3 个答案:

答案 0 :(得分:5)

我认为这就是你想要的:

@objc(MyClass)
class MyClass : NSObject {
    var someProperty = 0
}

let type = NSClassFromString("MyClass") as! NSObject.Type
let instance = type()
instance.setValue(12, forKey: "someProperty")

答案 1 :(得分:1)

我想出了这个(大)的例子:

class Car {
    // using static constants for quick refactoring (if you want)
    static let numberOfDoors = "numberOfDoors"
    static let carModel = "carModel"
    static let carMake = "carMake"
    static let carBrand = "carBrand"

    // dictionary for storing the values
    var properties = [
        Car.numberOfDoors : "",
        Car.carModel : "",
        Car.carMake : "",
        Car.carBrand : ""
    ]

    // computed properties to easily access the values
    // you probably don't need the setter
    var numberOfDoors: String {
        get{ return properties[Car.numberOfDoors]! }
        set{ properties[Car.numberOfDoors] = newValue }
    }
    var carModel: String {
        get{ return properties[Car.carModel]! }
        set{ properties[Car.carModel] = newValue }
    }
    var carMake: String {
        get{ return properties[Car.carMake]! }
        set{ properties[Car.carMake] = newValue }
    }
    var carBrand: String {
        get{ return properties[Car.carBrand]! }
        set{ properties[Car.carBrand] = newValue }
    }
}

所以最后你可能只需要这样的东西:

class Car {

    var properties = [
        "numberOfDoors" : "",
        "carModel" : "",
        "carMake" : "",
        "carBrand" : ""
    ]

    var numberOfDoors: String {
        return properties["numberOfDoors"]!
    }
    var carModel: String {
        return properties["carModel"]!
    }
    var carMake: String {
        return properties["carMake"]!
    }
    var carBrand: String {
        return properties["carBrand"]!
    }
}

正如您所看到的,Swift示例比Objective-C代码更复杂且更容易出错。因此,您应该考虑使用更静态的行为而不是动态行为。

答案 2 :(得分:1)

另一种解决方案是使Swift类成为NSObject的子类:

class Car : NSObject {
    var numberOfDoors = ""
    var carModel = ""
    var carMake = ""
    var carBrand = ""
}

let myNewObject =  Car()
myNewObject.setValue("4 doors", forKey: "numberOfDoors")
myNewObject.setValue("Prius", forKey: "carModel")
myNewObject.setValue("2014", forKey: "carMake")
myNewObject.setValue("Toyota", forKey: "carBrand")

但正如我之前所说,你应该考虑让它更加静态,以避免错别字来自拼写错误和复制粘贴代码。