我最近从BookTableViewController
的简单继承中重构了我的类UITableViewController
,因此它现在继承自通用类FetchedResultsTableViewController<TResultType, TCellType>
,它本身继承自UITableViewController
。
类声明如下所示:
class BookTableViewController: FetchedResultsTableViewController<Book, BookTableViewCell> {
override func viewDidLoad() {
// breakpoints in here do not catch!
}
}
class FetchedResultsTableViewController<TResultType, TCellType: UITableViewCell>:
UITableViewController, NSFetchedResultsControllerDelegate {
// implementation here
}
在Storyboard中,自定义类和模块都已设置,我可以单击箭头跳转到BookTableViewController
类的代码,表明故事板已正确链接上课。但是,当我尝试运行该应用程序时,无法识别该类 - viewDidLoad()
中的代码无法运行,并且在运行我的应用程序时收到以下已记录的消息:
Interface Builder文件中的未知类_TtC12Reading_List23BookTableViewController。
我正在运行XCode 7.3(Swift 2.2)。这是故事板的限制,一个错误,还是我错过了什么?
谢谢!
更新:
经过一些实验,它似乎与通用继承有关,而不是类的可访问性。定义了以下类:
import Foundation
import UIKit
// Both of these classes are accessible by the Storyboard
class FirstInheritance : UITableViewController{}
class SecondInheritance : FirstInheritance{}
// The generic class is also accessible
class GenericViewController<T> : UITableViewController{}
// But this class is not accessible...
class ConcreteViewController : GenericViewController<String>{}
除了ConcreteViewController
之外的所有类都在Storyboard的类自动完成中建议(尽管泛型类也不起作用,因为无法在Storyboard中指定类型参数)。
答案 0 :(得分:4)
游戏时间不多,但是这个信息可能会对任何碰到线程的人派上用场。
实际上,据我所知,现在,就Swift 3而言,在故事板中对泛型有一些尴尬的支持。
I&#39; VE管理写一个通用的基类延伸的UIViewController,然后约束即通用类的几个亚类,并在故事板使用它们
实际代码的布局与下面指定的类似:
class GenericParent: UIViewController {
// Has a few, non-generic members ...
}
class ActualGenericClass<T>: GenericParent {
// There are more generic members in the actual class
var adapter: Adapter<T> = Adapter()
}
// This class is usable in Interface Builder;
// although auto-complete won't show it, fully writing down
// the class name works
class SpecificInstanceOfActualGenericClass: ActualGenericClass<Int> {
@IBOutlet weak var tableView: UITableView!
}
令我惊讶的是,这完美无缺!
另一方面,下一个例子似乎不起作用:
class GenericCell<T>: UITableViewCell {
var node: T? = nil
}
class SpecificCell: GenericCell<Int> {
@IBOutlet weak var coolTitleLabel: UILabel!
}
和以前一样,在Interface Builder上明确地编写单元格的类名(在单元格的动态原型上)会在表格视图单元格上设置类,并且可以看到出口。
在运行时,虽然,实例化包含细胞&#39的UIViewController时; S动态原型中,&#34;界面生成器文件&#34未知类别;显示警告,并且在出列单元格时应用程序崩溃。
所以@Andew Bennet,声明:
故事板不支持从泛型类继承的类
似乎不再是100%的真实,尽管你至少是正确的;这是我第一次设法取消这一次,虽然只是部分的!
让我觉得有些事情有效,有些事情没有,但它总比没有好。
这在Java中非常简单......
答案 1 :(得分:2)
故事板不支持直接或间接从泛型类继承的类。如果您使用从故事板中的泛型类继承的类,则会在运行时收到错误,指出该类未知。
另一种方法是使用带有typealiases和扩展名的协议:
protocol MyProtocol {
associatedtype genericType1
associatedtype genericType2
func myFunc(argument1: genericType1, argument2: genericType2)
}
extension MyProtocol {
func defaultFunc(argument1: genericType1){
// default implementation here
}
}
协议使用如下:
class NonGenericClass: MyProtocol {
typealias genericType1 = Int
typealias genericType2 = String
func myFunc(argument1: genericType1, argument2: genericType2){
// specific implementation here
}
}
课程NonGenericClass
将包含MyProtocol
扩展程序中的所有功能(在本例中为defaultFunc(argument1: Int)
)。
协议MyProtocol
也可以从其他协议继承,那些功能的实现可以在MyProtocol
的扩展中定义。因此,协议可以使任何符合它的类也符合另一个协议,具有标准实现。
但是,这有一个限制,你不能在协议中指定类函数的标准覆盖。