Свойство isEnabled UIBarButtonItem является нераспознанным селектором в расширении класса.

В Swift 4 я хочу использовать расширение UIBarButtonItem, которое создает экземпляр специального объекта UIBarButtonItem.
Вот мой код (только основные операторы):

import Foundation

extension UIBarButtonItem {

    convenience init(staticImageName: String) {
        let staticView = UIImageView.init(image: UIImage(named: staticImageName))
        self.init(customView: staticView)
//      further code…
    }

    override open var isEnabled: Bool { 
        didSet { 
            print("didSet called") // Should be replaced by other code…
        } 
    } 

} // extension UIBarButtonItem

Это расширение собирается без проблем.

Однако когда я запускаю приложение, я получаю ошибку времени выполнения в операторе
self.init(customView: staticView).
В журнале говорится:

-[UIBarButtonItem isEnabled]: unrecognized selector sent to instance 0x7fe20c505180

Что не так с моим кодом?


person Reinhard Männer    schedule 11.12.2017    source источник
comment
isEnabled не является свойством UIBarButtonItem.   -  person Sagar Chauhan    schedule 11.12.2017
comment
@Jacky Но это свойство его суперкласса UIBarItem   -  person Reinhard Männer    schedule 11.12.2017
comment
Пожалуйста, обратитесь к этому, может быть, вам помогут: /   -  person Sagar Chauhan    schedule 11.12.2017
comment
Расширения предназначены для добавления новых функций. Расширения не должны использоваться для переопределения чего-либо. Создайте подкласс, если хотите переопределить. Из книги Swift: «Расширения могут добавлять новые функции к типу, но они не могут переопределять существующие функции».   -  person rmaddy    schedule 11.12.2017
comment
Была аналогичная проблема. Кажется, что isEnabled UIBarButtonItem не работает должным образом, начиная с Xcode 9 / iOS SDK 11. Я изменил UIBarButtonItem, чтобы использовать UIButton в качестве пользовательского представления, чтобы иметь возможность использовать isEnabled UIButton.   -  person Seryozha    schedule 11.12.2017
comment
@rmaddy Спасибо за разъяснения. Однако тогда возникает вопрос, почему это принимается компилятором. Собственно, мой код раньше был override var isEnabled: Bool {...}, а компилятор предложил Overriding var must be as accessible as the declaration it overrides и предложил в качестве исправления вставить open.   -  person Reinhard Männer    schedule 11.12.2017
comment
Я понятия не имею, почему компилятор Swift разрешает override в расширении, поскольку расширения не должны использоваться для переопределения чего-либо. Я бы назвал это ошибкой.   -  person rmaddy    schedule 11.12.2017
comment
@rmaddy В любом случае, это решение. Пожалуйста, опубликуйте это как ответ, чтобы я мог закрыть вопрос!   -  person Reinhard Männer    schedule 11.12.2017


Ответы (1)


Расширения не должны использоваться для переопределения каких-либо существующих функций. Предполагается, что расширения используются только для добавления новых функций.

Для главы «Расширения» в книге Swift:

«Расширения могут добавлять новые функции к типу, но они не могут переопределять существующие функции».

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

person rmaddy    schedule 11.12.2017