【问题标题】:Swift 5: 'self' used before 'self.init' callSwift 5:在“self.init”调用之前使用“self”
【发布时间】:2019-09-01 03:15:32
【问题描述】:

我正在尝试使用所需的便利可失败初始化程序。这是我正在使用的代码:

public init(authState: OIDAuthState, config: [String: String], accessibility: CFString = kSecAttrAccessibleWhenUnlockedThisDeviceOnly) throws {
        self.authState = authState
        self.config = config
        self.accessibility = accessibility

        super.init()

        KeycloakAuth.configuration = config
    }

public required convenience init?(coder aDecoder: NSCoder) {
        try? self.init(authState:     aDecoder.decodeObject(forKey: "authState")     as! OIDAuthState,
                       config:        aDecoder.decodeObject(forKey: "config")        as! [String: String],
                       accessibility: aDecoder.decodeObject(forKey: "accessibility") as! CFString)
    }

我在public required... 行收到错误'self' used before 'self.init' call,在try? self.init(... 行再次收到同样的错误。

我查看了有关 Stack Overflow 的其他一些相关问题。即这些:

  1. iOS Swift convenience initializer self used before self.init called
  2. 'self' used before self.init call error while using NSCoding on a custom class

所以我相应地安排了我的便利初始化,如果有任何问题,我会尝试返回 nil:

public required convenience init?(coder aDecoder: NSCoder) {
        guard
            let authState     = aDecoder.decodeObject(forKey: "authState")     as? OIDAuthState,
            let config        = aDecoder.decodeObject(forKey: "config")        as? [String: String]
        else {
            print("KeycloakTokenManager: There was an error intializing authState or config")
            return nil
        }

        let accessibility = aDecoder.decodeObject(forKey: "accessibility") as! CFString

        try? self.init(authState: authState, config: config, accessibility: accessibility)
    }

但我在相同的代码(初始化程序,并调用self.init)上得到相同的错误。有趣的是,我的项目在 Swift 4 上构建得很好,但我还没有听说过这是 Swift 5 的错误。我怎样才能摆脱这个错误?

【问题讨论】:

  • 不相关但为什么init(authState 标记为throws?实际上它根本不会抛出任何错误。
  • 好问题。这是来自另一个代码库的移植,所以我错过了那个细节。把它拿出来,一切都很好。
  • FWIW,上面的代码不会产生你在 Xcode 10.2 (10E125) 中对我说的错误。它必须是您在清理问题以在此处发布的过程中删除的内容。
  • 你运行的是什么版本的swift?
  • Xcode 版本 10.2 (10E125) 中的 Swift 5。在调用self.init(...) 之前,我没有看到self 的任何用途。

标签: swift initialization swift5


【解决方案1】:

这是我刚刚发现的另一种解决方案,它也有效。因为初始化器不抛出,所以最终代码可以是这样的:

public init(authState: OIDAuthState, config: [String: String], accessibility: CFString = kSecAttrAccessibleWhenUnlockedThisDeviceOnly) {
    self.authState = authState
    self.config = config
    self.accessibility = accessibility

    super.init()

    KeycloakAuth.configuration = config
}

public required convenience init?(coder aDecoder: NSCoder) {
    self.init(authState:     aDecoder.decodeObject(forKey: "authState")     as! OIDAuthState,
              config:        aDecoder.decodeObject(forKey: "config")        as! [String: String],
              accessibility: aDecoder.decodeObject(forKey: "accessibility") as! CFString)
}

【讨论】:

    【解决方案2】:

    解决办法是不调用指定的初始化器

    public required init?(coder aDecoder: NSCoder) {
        guard
            let authState     = aDecoder.decodeObject(forKey: "authState")     as? OIDAuthState,
            let config        = aDecoder.decodeObject(forKey: "config")        as? [String: String]
        else {
            print("KeycloakTokenManager: There was an error intializing authState or config")
            return nil
        }
    
        self.authState = authState
        self.config = config 
        self.accessibility =  aDecoder.decodeObject(forKey: "accessibility") as! CFString
    
        super.init()
    
        KeycloakAuth.configuration = config
    }
    

    【讨论】:

    • 去掉convenience关键字真的有什么损失吗?
    • convenience 意味着您必须在子类中调用指定的初始化程序,而您(现在)不需要。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多