"Unknown class in interface builder file" 当使用 class 时,它继承自 Storyboard 中的通用 class
"Unknown class in interface builder file" when using class which inherits from a generic class in a Storyboard
我最近从 UITableViewController
的简单继承重构了我的 class BookTableViewController
,因此它现在继承自一个泛型 class FetchedResultsTableViewController<TResultType, TCellType>
,它本身继承自 UITableViewController
.
class 声明如下所示:
class BookTableViewController: FetchedResultsTableViewController<Book, BookTableViewCell> {
override func viewDidLoad() {
// breakpoints in here do not catch!
}
}
class FetchedResultsTableViewController<TResultType, TCellType: UITableViewCell>:
UITableViewController, NSFetchedResultsControllerDelegate {
// implementation here
}
在 Storyboard 中,Custom class 和 Module 都设置好了,我 可以 点击箭头跳转到 BookTableViewController
的代码class,提示故事板已正确链接到 class。但是,当我尝试 运行 应用程序时,无法识别 class - viewDidLoad()
中的代码不会 运行,并且当 [=55] 时我收到以下记录的消息=]宁我的应用程序:
Unknown class _TtC12Reading_List23BookTableViewController in Interface Builder file.
我 运行宁 XCode 7.3 (Swift 2.2)。这是 Storyboard 的限制、错误,还是我遗漏了什么?
谢谢!
更新:
经过一些实验,它似乎确实与泛型继承有关,而不是 class 的可访问性。定义了以下 classes:
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
之外的所有 classes 都在 Storyboard 的 class 自动完成中建议(尽管通用 class 也不起作用,因为没有办法在 Storyboard 中指定类型参数)。
故事板不支持直接或间接继承自通用 classes 的 classes。如果您在情节提要中使用从泛型 class 继承的 class,您将在运行时收到一个错误,指出 class 未知。
另一种方法是使用带有类型别名和扩展名的协议:
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
}
}
class NonGenericClass
将具有 MyProtocol
扩展中的所有功能(在本例中,defaultFunc(argument1: Int)
)。
协议MyProtocol
也可以继承自其他协议,那些功能的实现可以定义在对MyProtocol
的扩展中。因此,协议可以使任何符合它的class也符合另一个协议,具有标准实现。
但是,这有一个限制,即您不能在协议中指定 class 函数的标准覆盖。
游戏有点迟了,但此信息可能对任何遇到该话题的人都有用。
实际上,据我所知,从 Swift 3 开始,故事板中对泛型的支持有些笨拙。
我已经设法编写了一个通用基础 class 扩展 UIViewController,然后约束该通用 class 的几个子 class 并在故事板中使用它们。
实际代码与下面指定的布局类似:
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 上(在单元的动态原型上)显式写入单元的 class 名称会在 table 视图单元上设置 class,并且插座可见。
但是,在运行时,当实例化包含单元格动态原型的 UIViewController 时,会显示 "unknown class in interface builder file" 警告,并且应用程序会在单元格出队时崩溃。
所以@Andew Bennet,声明:
Storyboards do not support classes which inherit from generic classes
虽然你至少是对的,但似乎不再是 100% 正确;这是我第一次成功实现这一目标,尽管只是部分实现!
有些东西有用,有些东西没用,这让我很烦恼,但总比没有好。
这在Java...
中太直截了当了
我最近从 UITableViewController
的简单继承重构了我的 class BookTableViewController
,因此它现在继承自一个泛型 class FetchedResultsTableViewController<TResultType, TCellType>
,它本身继承自 UITableViewController
.
class 声明如下所示:
class BookTableViewController: FetchedResultsTableViewController<Book, BookTableViewCell> {
override func viewDidLoad() {
// breakpoints in here do not catch!
}
}
class FetchedResultsTableViewController<TResultType, TCellType: UITableViewCell>:
UITableViewController, NSFetchedResultsControllerDelegate {
// implementation here
}
在 Storyboard 中,Custom class 和 Module 都设置好了,我 可以 点击箭头跳转到 BookTableViewController
的代码class,提示故事板已正确链接到 class。但是,当我尝试 运行 应用程序时,无法识别 class - viewDidLoad()
中的代码不会 运行,并且当 [=55] 时我收到以下记录的消息=]宁我的应用程序:
Unknown class _TtC12Reading_List23BookTableViewController in Interface Builder file.
我 运行宁 XCode 7.3 (Swift 2.2)。这是 Storyboard 的限制、错误,还是我遗漏了什么?
谢谢!
更新:
经过一些实验,它似乎确实与泛型继承有关,而不是 class 的可访问性。定义了以下 classes:
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
之外的所有 classes 都在 Storyboard 的 class 自动完成中建议(尽管通用 class 也不起作用,因为没有办法在 Storyboard 中指定类型参数)。
故事板不支持直接或间接继承自通用 classes 的 classes。如果您在情节提要中使用从泛型 class 继承的 class,您将在运行时收到一个错误,指出 class 未知。
另一种方法是使用带有类型别名和扩展名的协议:
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
}
}
class NonGenericClass
将具有 MyProtocol
扩展中的所有功能(在本例中,defaultFunc(argument1: Int)
)。
协议MyProtocol
也可以继承自其他协议,那些功能的实现可以定义在对MyProtocol
的扩展中。因此,协议可以使任何符合它的class也符合另一个协议,具有标准实现。
但是,这有一个限制,即您不能在协议中指定 class 函数的标准覆盖。
游戏有点迟了,但此信息可能对任何遇到该话题的人都有用。
实际上,据我所知,从 Swift 3 开始,故事板中对泛型的支持有些笨拙。
我已经设法编写了一个通用基础 class 扩展 UIViewController,然后约束该通用 class 的几个子 class 并在故事板中使用它们。
实际代码与下面指定的布局类似:
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 上(在单元的动态原型上)显式写入单元的 class 名称会在 table 视图单元上设置 class,并且插座可见。
但是,在运行时,当实例化包含单元格动态原型的 UIViewController 时,会显示 "unknown class in interface builder file" 警告,并且应用程序会在单元格出队时崩溃。
所以@Andew Bennet,声明:
Storyboards do not support classes which inherit from generic classes
虽然你至少是对的,但似乎不再是 100% 正确;这是我第一次成功实现这一目标,尽管只是部分实现!
有些东西有用,有些东西没用,这让我很烦恼,但总比没有好。
这在Java...
中太直截了当了