Swift 泛型和协议扩展
Posted
技术标签:
【中文标题】Swift 泛型和协议扩展【英文标题】:Swift Generics and Protocol Extensions 【发布时间】:2015-09-20 19:57:01 【问题描述】:我有一个协议Reusable
,它有一个静态函数static func reuseId() -> String
和一个定义函数默认实现的协议扩展。然后,我在UITableViewCell
上实现了一个扩展,以符合Reusable
协议。我现在可以毫无问题地在 TableViewCells 上使用该函数:SomeTableViewCell.reuseId()
。
我遇到的问题是泛型。我有一个泛型类,它具有UITableViewCell
类型的泛型参数:
internal class SomeClass<CellType: UITableViewCell>: NSObject
...
我希望能够在CellType
的泛型类中使用Reusable
中指定的函数,但不幸的是,这不能按预期工作。编译器总是生成错误Type 'CellType' has no member 'reuseId'
。
有人知道为什么会这样吗?有解决办法吗?
我正在使用 Xcode 7.0 和 Swift 2.0。
来自德国的问候
更新:这里有一些示例代码可以更好地显示我的问题:
import UIKit
protocol Reusable
static func reuseId() -> String
extension Reusable
static func reuseId() -> String
return String(self).componentsSeparatedByString(".").last!
extension UITableViewCell: Reusable
class SomeGenericClass<CellType: UITableViewCell>
func someFunction()
let reuseIdentifier = CellType.reuseId()
此代码会产生上述错误,但我不太明白为什么会发生这种情况。我认为 jtbandes 发布的示例代码的主要区别在于我使用了静态函数。
更新:该问题在 Xcode 8.3 beta 2 中得到修复。上面的示例代码现在可以按预期工作(当然是在将其迁移到 Swift 3 之后)。
【问题讨论】:
如果您发布实际代码的(最小)示例而不是仅描述问题,将会更有帮助。 我在原始问题中添加了示例代码,希望可以让我的问题更容易理解。 【参考方案1】:这是一个有趣的问题。您的代码似乎应该可以工作;你可能想file an enhancement request。
这是一个似乎可以正常工作的解决方法:
class SomeGenericClass<CellType: Cell>
func someFunction()
let reuseIdentifier = (CellType.self as Reusable.Type).reuseId()
【讨论】:
但是 CellType 继承自 UITableViewCell 已经符合 Reusable。在我看来,需要更多信息,我无法通过一个简单的示例重现该问题。 谢谢@MartinR,我想我误读了这个问题。是的,需要更多信息... 谢谢。我发布了一个雷达 22776964。您的解决方法似乎暂时可以正常工作,因此我会将您的答案标记为正确。一旦 Apple 回应雷达,我将更新问题。【参考方案2】:获得所需内容的另一种(解决方法)方法:
class GenericExample<CellType:UITableViewCell where CellType:Reusable>
func test() -> String
return CellType.reuseId()
GenericExample<UITableViewCell>().test() // returns "UITableViewCell"
GenericExample<MyCell>().test() // returns "MyCell"
【讨论】:
PS 原始场景很可能是一个错误,因为 XCode 中的自动完成模型知道 CellType 有一个 resuseID() 但编译器会抱怨否则以上是关于Swift 泛型和协议扩展的主要内容,如果未能解决你的问题,请参考以下文章
NSManagedObjectContext 扩展中泛型函数中的奇怪 Swift 行为
扩展类型的泛型和 Typescript 中的普通类型有啥区别?