0

我刚刚升级到 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),快速 3。

4

2 回答 2

1

我想跟进,因为接受的答案对我不起作用。所有这些都在 2017 年 6 月 12 日使用 Xcode 的 swift 4.0 开发快照工具链在操场上进行了测试。

这将失败并出现运行时异常

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. 我找到了 2 个对我有用的解决方案。

  1. 标记班级决赛

    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()
    
  2. 标记协议@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()
    
于 2017-06-20T21:33:27.723 回答
0

对崩溃的方法使用@objc

于 2017-06-18T03:56:33.037 回答