天天看點

Objective-C協定遵守NSObject協定的原因

來自我的個人部落格Minecode.link

今天将用OC寫的架構遷移至Swift時,發現OC寫的協定都遵守了NSObject,而在Swift中沒有此協定。是以記錄一下這個問題的原因:

在Objective-C 2.0之後,方法修飾符有@required和@optional(新增),也就是說增加了可選方法。對應的,也就需要在調用代理方法之前判斷其是否被實作。也就是我們熟悉的如下寫法:

if (self.delegate != nil && [self.delegate respondsToSelector:@selector(protocolFunc)]) {
    [self.delegate protocolFunc];
}
           

NSObject的協定主要定義了以下幾個常見方法:

  • - (BOOL)isKindOfClass:(Class)aClass;
  • - (BOOL)isMemberOfClass:(Class)aClass;
  • - (BOOL)conformsToProtocol:(Protocol *)aProtocol;
  • - (BOOL)respondsToSelector:(SEL)aSelector;
  • etc…

這就是為什麼我們需要繼承NSObject。

而Swift語言為我們提供了可選項,保證了調用的安全性,是以我們可以按如下方法使用:

// 定義協定
@objc protocol MCTestViewDelegate: class {
    @objc func testViewNeedsOperate()
    @objc optional func testViewDidUpdate()
}

/* ... */

// 判斷是否遵守協定并調用
if let delegate = testView is MCTestViewDelegate {
    delegate.testViewNeedsOperate()
}

// 判斷代理對象是否實作該代理方法
if (delegate as? MCTestViewDelegate)?.testViewDidUpdate != nil {
    // 處理...
}

// 一句話實作
(delegate as? MCTestViewDelegate)?.testViewDidUpdate?()
           

通過可選項的判斷,即可輕松判斷方法/協定是否實作,減少了代碼量。