如何在Swift中的便捷初始化器中调用类方法

时间:2015-01-28 05:42:54

标签: swift initialization

我正在尝试使用API​​,其中每个对象都以不同的方式命名其ID字段。示例:Group.groupid,Team.teamid等

我有一个BaseAPIObject,它有一个必需的初始化程序,它接受一个解析的JSON字典和一个简单的初始化程序,它只接受ID字段(我的类中唯一需要的属性)。

我通过添加一个静态的“class”方法来处理更改的id字段名称,该方法返回ID字段名称,子类覆盖该函数以返回它们自己的字段名称。

我遇到的问题是,在我的基类'方便初始化程序中,我在调用self.init()之前无法调用self.dynamicType但是我需要该静态类函数的结果才能正确构造我的对象

public class BaseAPIObject {
    var apiID: String!
    var name: String?
    var createdBy: String?
    var updatedBy: String?

    //Construct from JSONSerialization Dictionary
    required public init(_ data: [String: AnyObject]) {
        name        = data["name"] as String?
        createdBy   = data["created_by"] as String?
        updatedBy   = data["updated_by"] as String?

        super.init()

        let idName = self.dynamicType.idFieldName()
        apiID = data[idName] as String?
    }

    /// Creates an empty shell object with only the apiID set. 
    /// Useful for when you have to chase down a nested object structure
    public convenience init(id: String) {
        // THIS is what breaks! I can't call self.dynamicType here
        // How else can I call the STATIC CLASS method?
        // in ObjC this would be as simple as self.class.getIdFieldName()
        let idFieldName = self.dynamicType.getIdFieldName()
        let data = [idFieldName: id]
        self.init(data)
    }

    //This gets overridden by subclasses to return "groupid" or whatever
    class func idFieldName() -> String {
        return "id"
    }
}

问题:在实例本身上运行init之前,如何解决调用子类'类函数的问题?

1 个答案:

答案 0 :(得分:2)

不是创建用于计算id的类函数,而是创建init函数。由于您必须为每个子类创建这些函数之一,因此您并没有真正丢失任何东西。子类init函数然后使用id名称调用超级init。

这是一个例子,我改变了你的小组的一些属性只是为了让这个例子简单来说明这个概念。

public class BaseAPIObject {
    var objData: [String:String]

    required public init(_ data: [String: String]) {
        println("Data: \(data)")
        self.objData = data

    }

    public convenience init(id: String, idFieldName: String) {
        let data = [idFieldName: id]
        self.init(data)
    }
}

然后在你的子类中,概念上就是这样:

public class GroupObject: BaseAPIObject {
    public convenience init (id: String) {
        self.init(id: id, idFieldName: "group")
    }
}

let go = GroupObject(id: "foo")
println(go.objData["group"]!) //prints "foo"