2016-04-25 47 views
0

我正在嘗試創建一個協議,爲視圖控制器提供數據。我試圖採用協議方法並使事情變得靈活,所以視圖控制器可以使用任何類型的數據來符合。如何創建面向協議的通用服務?

不過,我發現了錯誤:Protocol 'Serviceable' can only be used as a generic contraint because it has Self or associated type requirements

這就是我想要做的事:

protocol Serviceable { 
    associatedtype DataType 
    func get(handler: ([DataType] -> Void)?) 
} 

struct PostService: Serviceable { 
    func get(handler: ([Postable] -> Void)? = nil) { 
     print("Do something...") 
    } 
} 

struct AuthorService: Serviceable { 
    func get(handler: ([Authorable] -> Void)? = nil) { 
     print("Do something...") 
    } 
} 

protocol Postable { 
    var title: String { get set } 
    var content: String { get set } 
} 

protocol ServiceControllable: class { 
    var service: Serviceable { get } // Error: Protocol 'Serviceable' can only be used as a generic contraint because it has Self or associated type requirements 
} 

extension ServiceControllable { 
    func setupDataSource() { 
     service.get { items in 
      // Do something 
     } 
    } 
} 

class MyViewController: ServiceControllable { 
    let service: Serviceable = PostService() // Error: Same as above 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     setupDataSource() 
    } 
} 

如何設置這使我的視圖控制器可以實現ServiceControllable和有權訪問填充表,集合等的通用setupDataSource?

回答

0

你想要這樣的東西。

import UIKit 

protocol Serviceable { 
    associatedtype DataType 
    func get(handler: ([DataType] -> Void)?) 
} 

struct PostService: Serviceable { 
    func get(handler: ([Postable] -> Void)? = nil) { 
     print("Do something...") 
    } 
} 

protocol Authorable {} 

struct AuthorService: Serviceable { 
    func get(handler: ([Authorable] -> Void)? = nil) { 
     print("Do something...") 
    } 
} 

protocol Postable { 
    var title: String { get set } 
    var content: String { get set } 
} 

protocol ServiceControllable: class { 

    // THIS is the way to use generic-constraint-protocols in protocols. 
    associatedtype _Serviceable: Serviceable 

    var service: _Serviceable { get } 

} 

extension ServiceControllable { 
    func setupDataSource() { 
     service.get { items in 
      // Do something 
     } 
    } 
} 

class MyViewController: UIViewController, ServiceControllable { 

    let service = PostService() 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     setupDataSource() 
    } 
} 

相關文件部分:Protocol Associated Type Declaratio