Этот код не компилируется и может казаться глупым, как есть, но я объясню, почему это так важно!Как использовать протокол @objc с дополнительными и расширениями одновременно?
@objc protocol p {
optional func f1()
func f2()
}
extension p {
func f1() { }
func f2() { }
}
class foo: p {
}
Компилятор говорит Type c does not conform to protocol 'p'
и что это может быть, потому что вы не можете использовать @objc необязательных и расширение в то же время (и не делаете Sence в этом случае тоже). Но рассмотрим следующий пример:
Я хочу, чтобы установить селектор на неопциональные метод, определенный в протоколе в моем расширения (основной причиной я использовал @objc):
func f1() { }
->func f1() { ... #selector(Self.f2) ... }
И Я также хочу, чтобы моя функция f2()
имела поведение по умолчанию. Если я отмечаю f2()
как optional
, он не может использоваться в #selector
, потому что компилятор не знает, действительно ли этот метод существует в случае необходимости. Конечно, существует множество неприятных обходных решений, таких как глобальные методы, отправка Selector
s методам ввода и т. Д., Но есть ли у них чистый способ его достижения?
Это практический вопрос
@objc
protocol Refreshable {
weak var refreshControl: UIRefreshControl? { get set }
optional func setupRefreshControl()
func refresh()
}
@objc
protocol ContentLoader {
func load(reset: Bool)
}
extension Refreshable where Self: ContentLoader {
func refresh() {
delay(0.75) { [weak self] in
self?.load(true)
}
}
}
extension Refreshable where Self: UICollectionViewController {
func setupRefreshControl() {
let newRefreshControl = UIRefreshControl()
newRefreshControl.tintColor = UIColor.grayColor()
newRefreshControl.addTarget(self, action: #selector(Self.refresh), forControlEvents: .ValueChanged)
collectionView?.addSubview(newRefreshControl)
refreshControl = newRefreshControl
}
}
Теперь, если ViewController реализует Refreshable
и ContentLoader
, он не находит функцию по умолчанию refresh
, но это найти setupRefreshControl
. Поэтому я решил, что давайте отметьте refresh
как необязательный вариант, но, сделав это, вы больше не можете отправлять его в селектор.
Я даже попытался это:
func refresh()
->optional func refresh()
и
let str = "refresh"
let sel = Selector(str)
Это Silents компилятор да, но не работает, либо ... поднимается unrecognized selector sent to instance....
Я не могу воспроизвести ваши ошибки. Пожалуйста, подумайте о размещении своего фактического кода (от 'f1' и' f2' и соответствующего кода для класса, который вы хотите соответствовать протоколу 'p'), чтобы другие и я могли вам помочь. Также, пожалуйста, прямо укажите, что вы пытаетесь выполнить, поскольку оно очень разбросано и неясно. – Ike10
Опционы будут проблемой с Objc. Возможно, что вы можете сделать, это настроить нескольких делегатов, каждый для определенной цели, и таким образом, если делегат не установлен, связанные функции не называются – Feldur
@ Ike10 Просто обновил вопрос :) – farzadshbfn