从父类自动返回子类类型的对象

时间:2017-09-29 15:39:34

标签: swift oop

所以基本上我有一个名为Model的父类,具有以下功能

static func allModels(complete: @escaping ([Model]) -> Void) {
    var models = [Model]()
    DatabaseHelper.firebase.child(getDB()).observeSingleEvent(of: .value) { (snapshot) in
        if let data = snapshot.value as? [String: Any] {
            for id in data.keys {
                if var modelData = data[id] as? [String: Any] {
                    modelData[MasterField.id] = id
                    let model = self.init(data: modelData)
                    models.append(model)
                }
            }
        }
        complete(models)
    }
}

它的效果很好,但事情就是这样。我有几个Model的子类,如" School"," Person"对于每个子类,我必须做这样的事情

static func all(complete: @escaping ([School]) -> Void) {
    super.allModels { (models) in
        complete(models as! [School])
    }
}

所有这一切都是调用方法并将结果转换为自己的类型。为每个子类的每个方法执行此操作真的很烦人。有没有办法从父类自动执行此操作?因此,调用School.all()会调用Model.all()但返回学校,而Person.all()也会调用Model.all()但返回一个人。

1 个答案:

答案 0 :(得分:1)

您可以使用Generics摆脱所有重复。

static func allModels<T>(complete: @escaping ([T]) -> Void)
    {
        var models = [T]()
        DatabaseHelper.firebase.child(getDB()).observeSingleEvent(of: .value) { (snapshot) in
            if let data = snapshot.value as? [String: Any] {
                for id in data.keys {
                    if var modelData = data[id] as? [String: Any] {
                        modelData[MasterField.id] = id
                        let model = self.init(data: modelData)
                        models.append(model as! T)
                    }
                }
            }
            complete(models)
        }
    }

值得注意的是,如果完成闭包所推断的类型与您调用allModels()的类不同,则强制向下转换(as!)将会崩溃。