Swift 5: «self» используется перед вызовом «self.init» - PullRequest
2 голосов
/ 10 апреля 2019

Я пытаюсь использовать обязательный удобный неудачный инициализатор.Вот код, с которым я работаю:

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)
    }

Я получаю ошибку 'self' used before 'self.init' call в строке public required... и ту же ошибку снова в строке try? self.init(....

Я посмотрел на несколько других связанных вопросов по переполнению стека.А именно:

  1. Удобный инициализатор iOS Swift, сам использованный до того, как self.init вызвал
  2. self, использованный до ошибки вызова self.init при использованииNSCoding для пользовательского класса

Поэтому я организовал свой удобный init соответствующим образом, чтобы попытаться вернуть 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. Как мне избавиться от этой ошибки?

Ответы [ 2 ]

3 голосов
/ 10 апреля 2019

Решение не вызывать назначенный инициализатор

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
}
0 голосов
/ 12 апреля 2019

Вот еще одно решение, которое я только что нашел, и которое мне кажется более элегантным, чем обходной путь, который я пытался.Поскольку инициализатор не выдает, окончательный код может быть таким:

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)
}
...