そのprotocol導入、意味ないかも


導入したはずのprotocolがconformsToProtocolに認識されない現象に遭ったので、それを読み解く。

前提

  • protocolはclass、extension、categoryのどちらも導入できる
  • extensionは静的、categoryは動的1

結論

  • protocolをextensionで書きたいなら、classのimplementationの見えるところ2に書こう
  • protocolをcategoryで書きたいなら、categoryのimplementationの見えるところに書こう

実験

UNUserNotificationCenterDelegateconformsToProtocolに認識されるか確認してみた。

  • AppDelegate.hをimportしているファイル
    • AppDelegate.m
    • AppDelegate+Hoge.m
  • AppDelegate+Hoge.hをimportしているファイル
    • AppDelegate+Hoge.m
  • AppDelegateのimplementationはAppDelegate.mにある
  • AppDelegateのcategoryのimplementationはAppDelegate+Hoge.mにある
  • チェック=conformsToProtocol

結果

  • AppDelegateでprotocolを導入
    • AppDelegate.hで定義
      • AppDelegate.mでチェック => YES
      • AppDelegate+Hoge.mでチェック => YES
    • ViewController.hで定義
      • AppDelegate.mでチェック => NO
      • AppDelegate+Hoge.mでチェック => NO
  • AppDelegateのextensionでprotocolを導入
    • AppDelegate.hで定義
      • AppDelegate.mでチェック => YES
      • AppDelegate+Hoge.mでチェック => YES
    • AppDelegate+Hoge.hで定義
      • AppDelegate.mでチェック => NO
      • AppDelegate+Hoge.mでチェック => NO
    • ViewController.hで定義
      • AppDelegate.mでチェック => NO
      • AppDelegate+Hoge.mでチェック => NO
  • AppDelegateのcategoryでprotocolを導入
    • AppDelegate.hで定義
      • AppDelegate.mでチェック => NO
      • AppDelegate+Hoge.mでチェック => NO
    • AppDelegate+Hoge.hで定義
      • AppDelegate.mでチェック => YES
      • AppDelegate+Hoge.mでチェック => YES
    • ViewController.hで定義
      • AppDelegate.mでチェック => NO
      • AppDelegate+Hoge.mでチェック => NO

上記の結果から分かるのは、

  • protocolの導入するinterfaceは、implementationが伴わないとconformsToProtocolは認識しない
  • ただし、種類によって認識するimplementationが違う:
    • AppDelegateに導入 => AppDelegateのimplementation
    • AppDelegateのextensionに導入 => AppDelegateのimplementation
    • AppDelegateのcategoryに導入 => AppDelegateのcategoryのimplementation

  1. http://quesera2.hatenablog.jp/entry/2014/02/22/202900 

  2. importされるヘッダーに、もしくは同じファイルに書く