2016-01-22 3 views
1

У меня есть реализация протокола следующим образом.Как вернуть `[Self]` из Swift Protocol?

protocol DatabaseInjectable { 

    static func deriveObjectFromDBRow(row: [String]) -> Self? // Method - 1 

    static func collectAllObjectsForDatabaseAction(action: (Database) -> Void) -> [Self]? // Method - 2 
} 

Где я успешно с реализацией корреспондент Method - 1, как это:

static func deriveObjectFromDBRow(row: [String]) -> Self? { 

    ... 
} 

Но я не мог Реализовать Method - 2 так:

static func collectAllObjectsForDatabaseAction(action: (WWDatabase) -> Void) -> [Self]? { 

    ... 
} 

Там я получаю сообщение об ошибке например:

'Self' is only available in a protocol or as the result of a method in a class; 

Любая помощь в возврате формы массива Self (класс, который он сам) будет приятным.

+1

Несмотря на то, что я ответил на несколько * похожих * вопросов (ни один из которых, я думаю, не ответил на ваш * конкретный вопрос), я до сих пор считаю обращение к «Я» неинтуитивным. Может быть, кто-то может написать окончательное руководство по этому вопросу ... – Grimxn

ответ

1

Если вы можете установить свой класс final вы можете заменить Self имя класса

final class SampleClass: DatabaseInjectable { 
    init() { 
    } 
    static func deriveObjectFromDBRow(row: [String]) -> SampleClass? { 
     return SampleClass() 
    } 

    static func collectAllObjectsForDatabaseAction(action: (Database) -> Void) -> [SampleClass]? { 
     let array = [SampleClass]() 
     return array 
    } 
} 
+0

Это может быть решение, но мне нужно подклассифицировать его. Поэтому я не могу установить его как класс «Final». – Goppinath

+0

Полезно знать, THX человек, это помогло мне. – tony508

0

Там очень хорошо письменный ответ here, но в общем, вы можете определить протокол, как например:


protocol DatabaseInjectable { 

    static func deriveObjectFromDBRow(row: [String]) -> DatabaseInjectable? // Method - 1 

    static func collectAllObjectsForDatabaseAction(action: (Database) -> Void) -> [DatabaseInjectable]? // Method - 2 
} 
+0

Спасибо, но мне нужен тип конкретного типа в качестве возвращаемого типа. То же, что и «instancetype» в Objective-C – Goppinath

0

Вы можете использовать typealias в своем протоколе DatabaseInjectable и использовать его как псевдоним для Self в классах, соответствующих вашему протоколу.

class Database { 
    var desc : String = "Default" 
} 

protocol DatabaseInjectable { 
    typealias MySelf 

    static func deriveObjectFromDBRow(row: [String]) -> MySelf? 

    static func collectAllObjectsForDatabaseAction(action: (Database) -> Void) -> [MySelf]? 
} 

class MyClass : DatabaseInjectable { 
    typealias MySelf = MyClass 

    static func deriveObjectFromDBRow(row: [String]) -> MySelf? { 
     return MyClass() 
    } 

    static func collectAllObjectsForDatabaseAction(action: (Database) -> Void) -> [MySelf]? { 
     return [MyClass(), MyClass()] 
    } 
} 

/* example */ 
let closure : (Database) ->() = { print($0.desc) } 
var arr : [MyClass]? = MyClass.collectAllObjectsForDatabaseAction(closure) 
/* [MyClass, MyClass] */ 

Один недостаток здесь, однако, что вы можете установить, например. typealias MySelf = Int (в классе), и ваши функции возвращают целое число/массив целых чисел (а не self/[Self]) и по-прежнему соответствуют вашему протоколу. Возможно, это разбойник.