使 swift 类符合协议 - 在静态/类级别
Posted
技术标签:
【中文标题】使 swift 类符合协议 - 在静态/类级别【英文标题】:Make swift class conform to protocol - at static/class level 【发布时间】:2015-04-18 01:37:29 【问题描述】:我正在尝试在 Swift 中构建一个通用的 UITableViewController 子类,它可以容纳任意数量的不同类型的表格视图单元格,而无需了解其中的任何一个。
为此,我尝试为我的模型和表格视图单元格使用协议。模型的协议将返回我应该去哪个单元格类别,而单元格的协议将返回对给定模型的单元格高度等问题的答案。
但是我在使协议工作时遇到问题,因为使用第二个协议我想进入单元的类而不是它的实例。
模型的协议如下:
protocol JBSTableItemDelegate
func tableCellDelegate() -> JBSTableViewCellInterface
细胞的协议如下:
protocol JBSTableViewCellInterface: class
static func registerNibsWithTableView(tableView: UITableView)
static func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath?, tableItem: JBSTableItemDelegate) -> CGFloat
static func tableView(tableView: UITableView, dequeueReusableCellWithIndexPath indexPath: NSIndexPath, tableItem: JBSTableItemDelegate, delegate: AnyObject) -> JBSTableViewCell
注意关键字“静态”的使用。这些方法是 UITableViewCell 子类中的类方法,添加静态似乎是我需要做的来验证这些类是否符合,或者我理解。
当我使用第一个协议时,代码如下所示,并且可以编译:
let tableViewCellInterface = tableItem!.tableViewCellInterface()
它正在调用这个方法(作为一个例子):
func tableViewCellInterface() -> JBSTableViewCellInterface
return JBSLiteratureTableViewCell.self as! JBSTableViewCellInterface
这会返回单元格的类,例如“JBSLiteratureTableViewCell.self”
当我使用第二个协议时,代码看起来像这样,并且无法编译:
returnFloat = tableViewCellInterface.tableView(tableView, heightForRowAtIndexPath: indexPath, tableItem: tableItem!)
由于之前的static关键字up导致编译失败,我得到的编译器错误是:
“JBSTableViewCellInterface”没有名为“tableView”的成员
如果我从协议函数中删除静态关键字,它会编译,但是 UITableViewCell 子类抱怨说:
'JBSLiteratureTableViewCell' 不符合协议'JBSTableViewCellInterface'
这是因为他们现在正试图确保实例方法存在,而实例方法并不存在。
如何使 swift 类符合类级别的协议,所以它可以是我的委托而不是类的某个实例?我确信我可以通过创建作为单例的协议 JBSTableViewCellInterface 的帮助程序类并让它们完成工作来解决这个问题,但我宁愿将它直接构建到其类方法中的 UITableViewCell 子类中。
【问题讨论】:
真的吗?有链接吗? 【参考方案1】:已针对 Swift 2.0 及更高版本更新
根据 Gregzo 的回答,Swift 2.0+ 允许在协议定义中将方法声明为静态。这些必须满足实现协议的对象中的静态/类方法。
您无法使用静态方法满足实例方法的协议定义,反之亦然,这使得对于上述问题的回答不完整。
如果你想试试这个,只需在你的协议定义中使用关键字“static”,你将在你的一致性对象中实现为静态或类方法:
protocol InstanceVsStatic
func someInstanceFunc()
static func someStaticFunc()
enum MyConformingEnum: InstanceVsStatic
case someCase
static func someStaticFunc()
// code
func someInstanceFunc()
// code
class MyConformingClass: InstanceVsStatic
class func someStaticFunc()
// code
func someInstanceFunc()
// code
struct MyConformingStruct: InstanceVsStatic
static func someStaticFunc()
// code
func someInstanceFunc()
// code
您可以让实例方法调用静态/类方法:
这允许您在需要符合需要实例方法的协议时执行静态代码。
struct MyConformingStruct: InstanceVsStatic
static func doStuffStatically()
// code
static func someStaticFunc()
// code
func someInstanceFunc()
MyConformingStruct.doStuffStatically()
Swift 1.2
除了上述的间接方法外,没有办法使用静态(类)方法来符合纯 Swift 1.2 及以下版本中的协议。这是一个已知的错误/未实现的功能:https://openradar.appspot.com/20119848
【讨论】:
想知道未来是否有可能推出一项功能?【参考方案2】:如果协议函数是静态的,则实现者应将其实现为静态方法,如果不是,则作为实例方法实现:
protocol MixedProtocol
static func staticFoo()
func instanceBar()
class ExampleClass : MixedProtocol
// implementing static func as class func is fine.
// class funcs are overridable, not static ones
class func staticFoo()
println( "I'm a class func" )
func instanceBar()
println( "I'm an instance func" )
没有直截了当的方法:遵守协议就是这样,“静态”是协议成员声明的关键特性,实现者必须尊重。
【讨论】:
以上是关于使 swift 类符合协议 - 在静态/类级别的主要内容,如果未能解决你的问题,请参考以下文章