Как создать базовый класс со слабым делегатом, который соответствует универсальному протоколу? - PullRequest
0 голосов
/ 27 мая 2018

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

class BaseView<P>: UIView {
    weak var delegate: P?
}

protocol MyProtocol {}

class MyView: BaseView<MyProtocol> {}

Это дает мне ошибку: «« слабый »не должен применяться к« T », не привязанному к классу; рассмотрите возможность добавления соответствия протокола, имеющего привязку к классу» ».

Как мне исправить эту ошибку?Или есть какая-то работа вокруг?Или это не так необходимо, чтобы вначале сделать делегатную переменную слабой?Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 31 мая 2018

Так как слабое - это свойство, назначаемое всему, что имеет тип класса, а не структуру, вы должны явно ограничить свой универсальный параметр типом класса, и вы делаете это следующим образом:

class BaseView<P: AnyObject>: UIView {
    weak var delegate: P?
}

@objc protocol MyProtocol {

}

class MyView: BaseView<MyProtocol> {

}

Толькоодно уточнение.Обычно для того, чтобы протокол был типом класса, обычно вы должны привести его в соответствие с классом следующим образом:

protocol MyProtocol: class { }

Однако по какой-то причине компилятор выдает ошибку, если вы сделаете это таким образом.Я узнал, что об этой ошибке можно узнать подробнее здесь:

Как потребовать, чтобы протокол мог быть принят только конкретным классом

Поэтому добавление@objc помогает заставить замолчать как предупреждение, так и ошибку.

0 голосов
/ 27 мая 2018

Вы должны добавить ограничение типа к своему универсальному, добавив MyProtocol и создать класс, который соответствует MyProtocol.

. Вы можете найти больше информации здесь .

Обновленный код:

class BaseView<P: MyProtocol>: UIView {
    weak var delegate: MyProtocol?
}

protocol MyProtocol: class {}

class MyProtocolImp: MyProtocol {

}

class MyView: BaseView<MyProtocolImp> {

}

Но я не знаю, почему вы используете P параметр в классе.Вы можете написать без этого:

class BaseView: UIView {
    weak var delegate: MyProtocol?
}

protocol MyProtocol: class {}

class MyView: BaseView {

}
...