Требуется: элегантная реализация validateUserInterfaceItem для составления протокола - PullRequest
0 голосов
/ 02 апреля 2019

У меня есть NSOutlineView с базовой моделью, состоящей из узлов. Эти узлы имеют множество различных возможностей, созданных с помощью протоколов.

РЕДАКТИРОВАТЬ - чтобы уточнить, возможности, описанные каждым протоколом, реализованы как расширения протокола по умолчанию в расширениях, поэтому в настоящее время подклассы не должны содержать какие-либо методы для соответствия протоколу.

У меня есть NSMenu, который содержит действия, которые могут быть выполнены на Node s в представлении.

Я хотел бы проверить пункты меню для текущего выбранного Node, но я не могу придумать, как это сделать, не написав одну массивную функцию для базового класса.

Проверки, которые мне нужны, - это не просто соответствие протокола - например, Node, который реализует протокол Indentable, не может иметь отступ при любых обстоятельствах. Мне нужен canIndent(), чтобы дополнить метод indent().

Давным-давно в C ++ я реализовал нечто подобное, построив таблицу проверки в виде статического массива для базового класса. Подклассы регистрируют свои методы при запуске. Однако при использовании Swift я не могу поместить выражения на верхний уровень, чтобы сделать это чисто, и нет кода инициализации на уровне протокола.

Единственный способ, которым я могу думать сейчас, - это использовать метод на Узле в такой форме:

func validAction(_ action: Selector) -> Bool
{
    switch(action)
    {
    case #selector(indent):
        if self is Indentable {
            return (self as! Indentable).canIndent

        ...

РЕДАКТИРОВАТЬ - Как отметил Виллек, я мог написать это на каждом подклассе, который соответствует протоколу, но это потребовало бы много повторений.

В идеале я бы построил метод на узле вида:

func validAction(_ action: Selector) -> Bool 
{
    if self.responds(to: action) {
        return validations[action].valid
    } 

    return false
}

Кто-нибудь делал это хорошо!?

РЕДАКТИРОВАТЬ - Одна из идей может заключаться в том, чтобы что-то сделать с описанием селектора для создания селектора проверки с соглашением об именах - например, indent() -> indentValid()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...