【问题标题】:How to create protocol-oriented generic services?如何创建面向协议的通用服务?
【发布时间】:2016-04-25 12:05:43
【问题描述】:

我正在尝试创建一个为视图控制器提供数据的协议。我正在尝试采用协议方法并使事情变得灵活,因此视图控制器可以使用任何类型的数据进行一致性。

但是,我收到错误消息: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?

【问题讨论】:

    标签: ios swift generics swift2 protocols


    【解决方案1】:

    你想要这样的东西。

    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.

    【讨论】:

      猜你喜欢
      • 2021-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多