Подтвердить что ты не робот

Параметрируемый Неудачный инициализатор для подкласса NSObject

Я хотел бы предоставить инициализатор с отказом для подкласса NSObject для инициализации без параметров. Моя общая цель - вернуть нуль, этот класс инициализируется на версию ОС менее 8.0.

Моя попытка:

class MyObject: NSObject {
    override init?() {
        super.init()
        if floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1 {
            return nil
        }

    }
}

Однако этот код приводит к следующей ошибке компилятора.

Failable initializer 'init()' cannot override a non-failable initializer

Можно ли переопределить init(), чтобы обеспечить отказоустойчивую реализацию в подклассе? Или есть лучший способ достичь этой цели?

4b9b3361

Ответ 1

Как вы подклассифицируете NSObject, у вас не может быть инициализатор без параметров, поскольку NSObject не инициализирует параметр.

Вы можете создать метод класса factory, который возвращает экземпляр или нуль в зависимости от версии iOS

Ответ 2

Учитывая, что:

Вы можете переопределить инициализатор с возможностью инициализации с незавершенным инициализатором, но не наоборот.

и

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

(выдержки из Отказоустойчивые инициализаторы)

и принимая во внимание, что NSObject не имеет инициализатора с параметром без параметров, то нет, вы не можете переопределить инициализатор без сбоев с инициализатором с ошибкой.

Единственная опция, которую я вижу, это создать инициализатор с фиктивным параметром, например:

class MyObject: NSObject {
    init?(_ ignore: Bool) {
        super.init()
        if floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1 {
            return nil
        }
    }
}

а затем используя его как:

var myObj = MyObject(true)

или

var myObj = MyObject(false)

Более интересно, присвоение значения по умолчанию параметру фиктивной, похоже, делает работу довольно хорошо:

class MyObject: NSObject {
    init?(_ ignore: Bool = false) {
        super.init()
        if floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1 {
            return nil
        }
    }
}

var myObj = MyObject()