6

我一直在玩协议扩展,但遇到了问题。也许我想要达到的目标无法完成。我有这个游乐场:

//: Playground - noun: a place where people can play

import UIKit

protocol ArrayContainer {
    typealias T
    var array: [T] { get }
}

class MyViewController: UIViewController, ArrayContainer, UITableViewDataSource {
    typealias T = String
    var array = ["I am", "an Array"] 
}

extension UITableViewDataSource where Self: ArrayContainer {

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return array.count
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        // Whatever
        return UITableViewCell()
    }   
}

这就是我所拥有和想要的:

  • 我有一个协议 <code>ArrayContainer​,它只有一个 typealias 和一个包含此 typealias 类型对象的数组
  • 我有一个<code>UITableViewDataSource​的协议扩展,当类符合​<code>ArrayController​协议时使用。这只是将数组的项目数作为行数返回。该cellForRowAtIndexPath方法没有很好地实现,但这不是问题。
  • 我有一个名为<code>MyViewController​的​<code>UIViewController​子类,它实现了这两种协议。

问题是编译器抱怨因为 MyViewController 不符合,UITableViewDataSource但据我所知,它应该被 UITableViewDataSource 扩展覆盖。我在这里错过了什么吗?或者可能无法扩展 Objective-C 协议?

4

1 回答 1

5

我知道现在回复有点晚了,你甚至可能都没有在寻找这个答案,但我刚刚遇到了这个确切的问题,需要一个现实世界的“解决方案”。您可以在类中实现 UITableViewDataSource 方法,然后立即将工作交给协议扩展,如下例所示。如果 swift 进行了不再需要的改进,则可以很容易地改回原始帖子中的代码。

//: Playground - noun: a place where people can play

import UIKit

protocol ArrayContainer {
    associatedtype T
    var array: [T] { get }
}

class MyViewController: UIViewController, ArrayContainer, UITableViewDataSource {
    typealias T = String
    var array = ["I am", "an Array"]

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return self.internal_numberOfSectionsInTableView(tableView)
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.internal_tableView(tableView, numberOfRowsInSection: section)
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        return self.internal_tableView(tableView, cellForRowAtIndexPath: indexPath)
    }
}

extension UITableViewDataSource where Self: ArrayContainer {

    func internal_numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    func internal_tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return array.count
    }

    func internal_tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        // Whatever
        return UITableViewCell()
    }   
}
于 2016-05-26T17:14:20.580 回答