2015-01-28 2 views
0

Я пытаюсь использовать API, где каждый объект по-разному называет его поле идентификатора. Пример: Group.groupid, Team.teamid и т. Д.Как вызвать метод класса в инициализаторе удобства в Swift

У меня есть BaseAPIObject, у которого есть необходимый инициализатор, который принимает анализируемый словарь JSON и инициализатор удобства, который занимает только поле ID (единственное необходимое свойство моего класса) ,

Я занимался изменением имен полей идентификаторов, добавив статический метод «класс», который возвращает имя поля и подклассы идентификатора, переопределяя эту функцию, чтобы вернуть свое собственное имя поля.

Проблема заключается в том, что в инициализаторе удобства базового класса я не могу вызвать self.dynamicType до того, как я вызвал self.init(), но мне нужны результаты этой статической функции класса, прежде чем я смогу правильно построить мой объект.

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" 
    } 
} 

Вопрос: Как я могу решить эту проблему вызова подкласса функции класса перед запуском инициализации на например сами?

ответ

2

Вместо создания функции класса для определения идентификатора вместо этого создайте функции init. Поскольку вам уже нужно создать одну из этих функций для каждого подкласса, вы на самом деле ничего не теряете. Затем функция init подкласса вызывает init супер с именем id.

Вот пример, я изменил некоторые свойства вашей группы только для того, чтобы сделать пример простым, чтобы проиллюстрировать концепцию.

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" 
+0

Это то, что я в конечном итоге делает прошлой ночью, чтобы обойти эту проблему, но я до сих пор сохранить функцию класса, потому что я также используйте его в init по-другому, что я не могу обойти эту же технику. Если никто другой не придумает что-то, я приму этот ответ. –

Смежные вопросы