如何在Swift 3中实例化Base类中的Object

时间:2016-11-14 21:57:45

标签: ios iphone swift

我有一个ModelBase类,我从它的子类中有几个类(即Task,Milestone等)。我想创建一个名为“all”的静态方法,它将获取所有模型(比如说一个数组),但我希望数组的类型为[Task]而不是[ModelBase]。虽然我不想为每个子类编写该方法,如果可能的话。

class Task: ModelBase {
    override class var tableName : String {return "Task"}

}

然后我可以做:

Task.all({ (tasks:[Task]) in  
   // do stuff with tasks
});

到目前为止,我一直在使用type(of:self)来访问非静态/类方法中的类级变量。

但是,我想有一个静态方法可以从API中获取模型,但我无法弄清楚如何引用当前类(即本例中的任务)

请告诉我,如果我想做的事情有意义/是可能的。这是我从解析中获取的示例代码。

class ModelBase: NSObject {

// THIS WORKS FINE --->
class var tableName : String {return "ModelBase"}

init(_ _dictionary: [String: Any]) {

        self.dictionary = _dictionary
        _parseObject =  PFObject(className: type(of: self).tableName)
}

// THIS IS WHAT FAILS --------------> 
 class func all(_ success: @escaping ([ModelBase]) ->(), failure: @escaping (Error) -> ()){
    var models  = [ModelBase]()
    let questsQuery = PFQuery(className: ModelBase.tableName)

    questsQuery.findObjectsInBackground {
        (objects: [PFObject]?, error: Error?) -> Void in

        if let error = error {
            failure(error)
        } else {
            if let objects = objects {
                for object in objects {
                    models.append(  ModelBase(parseObject: object as PFObject))
                }
                success(models)
            } else {
                success([])
            }
        }
    }
} 

}

2 个答案:

答案 0 :(得分:0)

您的问题有点令人困惑,但假设您要将ModelBase.tableName替换为类似self.tableName的内容,而不是基类表名,则需要使用class func所以它可以被子类

覆盖
class ModelBase {
    class func tableName() -> String {
        return "base"
    }

    class func all() {
        print(self.tableName())
    }
}

class UserModel: ModelBase {
    override class func tableName() -> String {
        return "user"
    }
}

ModelBase.all() // base
UserModel.all() // user

答案 1 :(得分:0)

如果我理解正确,你希望这个代码在ModelBase的任何子类上都是多态的。为此,我建议使用泛型。

class func all<T: ModelBase>(_ success: @escaping ([T]) ->(), failure: @escaping (Error) -> ()) {
    let questsQuery = PFQuery(className: T.tableName)

    questsQuery.findObjectsInBackground {
        (objects: [PFObject]?, error: Error?) -> Void in

        if let error = error {
            failure(error)
            return
        } 

        guard let objects = objects else {
            success([])
            return
        }

        let models = objects.map(T.init(parseObject:))
        success(models)
    }
}
相关问题