Xcode 9.0 Beta:调用 Type.init() 时 swift "cannot init a class object"
Xcode 9.0 Beta: swift "cannot init a class object" when calling Type.init()
我刚刚升级到 Xcode 9.0 Beta,现在我的应用程序在启动时崩溃了。
2017-06-09 14:35:18.817213-0700 recharge-consumer-ios[13524:1720597] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** +[recharge_consumer_ios.SignedOutContainerViewController<0x105c691b8> init]: cannot init a class object.'
*** First throw call stack:
(
0 CoreFoundation 0x000000010caf4f6b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x000000010ba3e121 objc_exception_throw + 48
2 CoreFoundation 0x000000010cb7f6ff +[NSObject(NSObject) init] + 127
3 recharge-consumer-ios 0x0000000105322223 _T021recharge_consumer_ios22RechargeViewControllerCACycfCTD + 19
失败的调用是(简化):
func setAndRefreshChildViewControllersWithTypes(_ types: [MyViewControllerProtocol.Type]) {
for type in types {
let controller = type.init() as! UIViewController // This is what crashes
}
...
}
其中 MyViewControllerProtocol
是:
protocol MyViewControllerProtocol {
// some other fields here too
init()
}
失败的实例如下所示:
class SignedOutContainerViewController: MyViewController {
required init() {
super.init(nibName: "SignedOutContainerViewController")
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
其中 MyViewController
是:
class MyViewController: UIViewController, MyViewControllerProtocol {
required init() {
fatalError("init has not been implemented")
}
init(nibName nibNameOrNil: String?) {
super.init(nibName: nibNameOrNil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
知道出了什么问题,或者有其他地方可以查看的指示吗? Xcode 9.0 测试版 (9M136h),swift 3.
对崩溃的方法使用@objc
我想跟进,因为已接受的答案对我不起作用。所有这些都是在操场上使用 swift 4.0 开发快照工具链进行测试的 Xcode 从 2017 年 6 月 12 日开始。
这将因运行时异常而失败
import Foundation
public protocol MyProtocol {
init()
}
@objc // This doesn't work
public class MyClass: NSObject, MyProtocol {
@objc // This doesn't work either
required public override init() {
super.init()
}
}
let anonymousType: AnyClass = MyClass.self
let metaType: MyProtocol.Type = anonymousType as! MyProtocol.Type
let instance = metaType.init()
对我来说,这并不像用 @objc
标记 class 或方法那么简单。我找到了 2 个适合我的解决方案。
标记class决赛
import Foundation
public protocol MyProtocol {
init()
}
final public class MyClass: NSObject, MyProtocol {
required public override init() {
super.init()
}
}
let anonymousType: AnyClass = MyClass.self
let metaType: MyProtocol.Type = anonymousType as! MyProtocol.Type
let instance = metaType.init()
标记协议@objc
import Foundation
@objc
public protocol MyProtocol {
init()
}
public class MyClass: NSObject, MyProtocol {
required public override init() {
super.init()
}
}
let anonymousType: AnyClass = MyClass.self
let metaType: MyProtocol.Type = anonymousType as! MyProtocol.Type
let instance = metaType.init()
我刚刚升级到 Xcode 9.0 Beta,现在我的应用程序在启动时崩溃了。
2017-06-09 14:35:18.817213-0700 recharge-consumer-ios[13524:1720597] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** +[recharge_consumer_ios.SignedOutContainerViewController<0x105c691b8> init]: cannot init a class object.'
*** First throw call stack:
(
0 CoreFoundation 0x000000010caf4f6b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x000000010ba3e121 objc_exception_throw + 48
2 CoreFoundation 0x000000010cb7f6ff +[NSObject(NSObject) init] + 127
3 recharge-consumer-ios 0x0000000105322223 _T021recharge_consumer_ios22RechargeViewControllerCACycfCTD + 19
失败的调用是(简化):
func setAndRefreshChildViewControllersWithTypes(_ types: [MyViewControllerProtocol.Type]) {
for type in types {
let controller = type.init() as! UIViewController // This is what crashes
}
...
}
其中 MyViewControllerProtocol
是:
protocol MyViewControllerProtocol {
// some other fields here too
init()
}
失败的实例如下所示:
class SignedOutContainerViewController: MyViewController {
required init() {
super.init(nibName: "SignedOutContainerViewController")
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
其中 MyViewController
是:
class MyViewController: UIViewController, MyViewControllerProtocol {
required init() {
fatalError("init has not been implemented")
}
init(nibName nibNameOrNil: String?) {
super.init(nibName: nibNameOrNil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
知道出了什么问题,或者有其他地方可以查看的指示吗? Xcode 9.0 测试版 (9M136h),swift 3.
对崩溃的方法使用@objc
我想跟进,因为已接受的答案对我不起作用。所有这些都是在操场上使用 swift 4.0 开发快照工具链进行测试的 Xcode 从 2017 年 6 月 12 日开始。
这将因运行时异常而失败
import Foundation
public protocol MyProtocol {
init()
}
@objc // This doesn't work
public class MyClass: NSObject, MyProtocol {
@objc // This doesn't work either
required public override init() {
super.init()
}
}
let anonymousType: AnyClass = MyClass.self
let metaType: MyProtocol.Type = anonymousType as! MyProtocol.Type
let instance = metaType.init()
对我来说,这并不像用 @objc
标记 class 或方法那么简单。我找到了 2 个适合我的解决方案。
标记class决赛
import Foundation public protocol MyProtocol { init() } final public class MyClass: NSObject, MyProtocol { required public override init() { super.init() } } let anonymousType: AnyClass = MyClass.self let metaType: MyProtocol.Type = anonymousType as! MyProtocol.Type let instance = metaType.init()
标记协议@objc
import Foundation @objc public protocol MyProtocol { init() } public class MyClass: NSObject, MyProtocol { required public override init() { super.init() } } let anonymousType: AnyClass = MyClass.self let metaType: MyProtocol.Type = anonymousType as! MyProtocol.Type let instance = metaType.init()