如何在 Swift 的便捷初始化器中调用 class 方法
How to call a class method in a convenience initializer in Swift
我正在尝试使用一个 API,其中每个对象都以不同的方式命名其 ID 字段。示例:Group.groupid、Team.teamid 等
我有一个 BaseAPIObject
,它有一个接受解析的 JSON 字典的必需初始化程序和一个只接受 ID 字段的便利初始化程序(我的 属性 唯一需要的=34=]).
我已经通过添加静态又名 "class" 方法来处理不断变化的 ID 字段名称,该方法 returns ID 字段名称和 subclasses 将该函数覆盖到 return自己的字段名。
我遇到的问题是,在我的基础 class' 便利初始值设定项中,我无法在调用 self.init() 之前调用 self.dynamicType,但我需要以下结果在我可以正确构造我的对象之前那个静态 class 函数。
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 之前调用 subclass' class function 的问题=24=]实例本身?
与其创建 class 函数来计算 ID,不如创建 init 函数。由于您已经必须为每个 subclass 创建这些函数之一,因此您并没有真正失去任何东西。 subclasses init 函数然后使用 id name.
调用 super 的 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)
}
}
然后在你的子class中,概念上是这样的:
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"
我正在尝试使用一个 API,其中每个对象都以不同的方式命名其 ID 字段。示例:Group.groupid、Team.teamid 等
我有一个 BaseAPIObject
,它有一个接受解析的 JSON 字典的必需初始化程序和一个只接受 ID 字段的便利初始化程序(我的 属性 唯一需要的=34=]).
我已经通过添加静态又名 "class" 方法来处理不断变化的 ID 字段名称,该方法 returns ID 字段名称和 subclasses 将该函数覆盖到 return自己的字段名。
我遇到的问题是,在我的基础 class' 便利初始值设定项中,我无法在调用 self.init() 之前调用 self.dynamicType,但我需要以下结果在我可以正确构造我的对象之前那个静态 class 函数。
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 之前调用 subclass' class function 的问题=24=]实例本身?
与其创建 class 函数来计算 ID,不如创建 init 函数。由于您已经必须为每个 subclass 创建这些函数之一,因此您并没有真正失去任何东西。 subclasses init 函数然后使用 id name.
调用 super 的 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)
}
}
然后在你的子class中,概念上是这样的:
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"