2015-12-04 1 views
1

Допустим, у нас есть протокол, в Swift:Swift протокол @objc - различают дополнительные методы с аналогичной подписью

@objc protocol FancyViewDelegate { 
    optional func fancyView(view: FancyView, didSelectSegmentAtIndex index: Int) 
    optional func fancyView(view: FancyView, shouldHighlightSegmentAtIndex index: Int) -> Bool 
} 

Обратите внимание, что оба метода не являются обязательными и имеют одинаковый префикс подписи.

Теперь наш FancyView класс выглядит следующим образом:

class FancyView: UIView { 
    var delegate: FancyViewDelegate? 

    private func somethingHappened() { 
    guard let delegateImpl = delegate?.fancyView else { 
     return 
    } 

    let idx = doALotOfWorkToFindTheIndex() 

    delegateImpl(self, idx) 
    } 
} 

Компилятор прыгает в лицо:

enter image description here

Мы могли бы изменить somethingHappened() к этому:

private func somethingHappened() { 
    let idx = doALotOfWorkToFindTheIndex() 

    delegate?.fancyView?(self, didSelectSegmentAtIndex: idx) 
} 

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

Вопрос: Как нам if let или guard let связывать реализацию двух необязательных методов с аналогичной сигнатурой префикса.

+0

Я бы по-прежнему использовал responsesToSelector и вызывал соответствующий метод, если он поддерживается. – Shripada

ответ

0

Во-первых, ваш объективный протокол C должен подтвердить NSObjectProtocol, чтобы убедиться, что он поддерживает данный метод.

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

@objc protocol FancyViewDelegate : NSObjectProtocol { 
     optional func fancyView(view: UIView, didSelectSegmentAtIndex index: Int) 
     optional func fancyView(view: UIView, shouldHighlightSegmentAtIndex index: Int) -> Bool 
    } 


    class FancyView: UIView { 
     var delegate: FancyViewDelegate? 

     private func somethingHappened() { 
     if delegate?.respondsToSelector("fancyView:didSelectSegmentAtIndex") == true { 
      let idx :Int = 0 //Compute the index here 
      delegate?.fancyView!(self, didSelectSegmentAtIndex: idx) 
     } 
     } 
    }