这是看起来足够简单,但并不像您期望的那样工作的事情之一。
我正在为我的类开发一个“流畅/链接”风格的 API,以允许您通过可以链接在一起的函数来设置属性,这样您就不必对初始化程序发疯了。此外,它在使用共享相同 API 的 map、filter 和 reduce 等函数时更加方便。
考虑这个 RowManager
扩展...
extension RowManager
{
@discardableResult
public func isVisible(_ isVisible:Bool) -> RowManager
{
self.isVisible = isVisible
return self
}
}
这完全符合人们的预期。但是这里有一个问题……如果您正在使用 RowManager
的子类,这会将对象向下转换回 RowManager
,从而丢失所有特定于子类的详细信息。
“别担心!”我想。 “我将只使用 Self
和 self
来处理类型!”所以我把它改成了这个...
extension RowManager
{
@discardableResult
public func isVisible(_ isVisible:Bool) -> Self // Note the capitalization representing the type, not instance
{
self.isVisible = isVisible
return self // Note the lowercase representing the instance, not type
}
}
...但是由于某种原因甚至无法编译并给出以下错误...
Command failed due to signal: Segmentation fault: 11
更新
做更多的研究,这似乎是因为我们的代码既在动态库中,也使用动态库。 SO 上的其他问题也讨论了这些情况下的特定错误。也许这是编译器的错误,因为正如其他人正确指出的那样,这段代码在独立测试中运行良好,但一旦在我们的代码中进行更改,就会出现段错误。
回想起与返回该类型实例的类函数类似的事情,我想起了您必须如何使用私有(private)泛型函数来进行实际的转换,所以我尝试将该模式与以下内容匹配...
extension RowManager
{
@discardableResult
public func isVisible(_ isVisible:Bool) -> Self // Note the capitalization
{
self.isVisible = isVisible
return getTypedSelf()
}
}
private func getTypedSelf<T:RowManager>() -> T
{
guard let typedSelfInstance = self as? T
else
{
fatalError() // Technically this should never be reachable.
}
return typedSelfInstance
}
不幸的是,这也不起作用。
作为引用,这里是基于类的代码,我试图以此为基础(className 是另一个扩展,它只返回您调用它的类的名称的字符串表示形式)...
extension UITableViewCell
{
/// Attempts to dequeue a UITableViewCell from a table, implicitly using the class name as the reuse identifier
/// Returns a strongly-typed optional
class func dequeue(from tableView:UITableView) -> Self?
{
return self.dequeue(from:tableView, withReuseIdentifier:className)
}
/// Attempts to dequeue a UITableViewCell from a table based on the specified reuse identifier
/// Returns a strongly-typed optional
class func dequeue(from tableView:UITableView, withReuseIdentifier reuseIdentifier:String) -> Self?
{
return self.dequeue_Worker(tableView:tableView, reuseIdentifier:reuseIdentifier)
}
// Private implementation
private class func dequeue_Worker<T:UITableViewCell>(tableView:UITableView, reuseIdentifier:String) -> T?
{
return tableView.dequeueReusableCell(withIdentifier: reuseIdentifier) as? T
}
}
最佳答案
Apple 在 WWDC 上确认这是一个 Swift 编译器问题,我们的代码库中的其他东西正在触发,并补充说在任何情况下都不应该出现编译器出现 Seg11 错误的情况,所以这个问题实际上是无效的。现在关闭它,但如果他们解决了它,我会报告回来。
关于swift - 在 Swift 中,你能写一个扩展,它返回扩展所在类的类型化实例吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44007332/