2016年10月5日水曜日

Xcode8:'undeclared selector' warning対応

<ワーニング内容>

  • 下記例のように別クラス内のセレクタメソッドを呼び出すコーディングでセレクター名が見つからない場合に発生するコンパイラWarning。
  • // warningエラー発生例
    - (IBAction)togglePreferences:(id)sender
    {
        // Setting画面へ切り替え
        [_canvasScene.layerCanvasMenu performSelector:@selector(tappedSettingButton:) withObject:nil];
    }
    

<対応方法>

  1. コンパイラオプションで無効化
    ・当Warningが大きなお世話であればコンパイラオプションで全体的に無効化する事は可能。
    └ 飛び先不明をコンパイル時にチェック出来る意味が無くなる。
  2. 当Warningをコード回避
    // warningエラー回避コーディング
    - (IBAction)togglePreferences:(id)sender
    {
        // Setting画面へ切り替え
    //    [_canvasScene.layerCanvasMenu performSelector:@selector(tappedSettingButton:) withObject:nil];
        SEL selector = sel_registerName("tappedSettingButton:");
        [_canvasScene.layerCanvasMenu performSelector:selector withObject:nil];
    }
    
    ・一旦、sel_registerName関数でセレクタ変数化して指定する事でWarningチェックを回避。
    └ セレクタ名のタイプミスに対応できない。
  3. 外部参照セレクタをヘッダーファイル定義
    ・呼び出し先クラスのヘッダファイル(上記例:layerCanvasMenu.h)内に外部からの参照(呼び出し)を許可するセレクタメソッドをカテゴリ機能を用いて宣言する。
  4. // ----- 外部参照セレクタ宣言 --------------------------------------------------------------------------
    @interface CanvasMenuLayer(external_selector)
    - (void)tappedSettingButton:(id)sender;
    @end

<所感>

  • セレクタ指定呼び出しでセレクタが存在しない実行時エラーをコンパイル時にチェックできるのはありがたい機能。
    └ エディタのコードアシスト機能でタイプミスも少ないけど、コンパイル時チェックは可能なら実施すべき。
  • 上記「対応方法」として3種類あげていますが、本来のコンパイル時チェックの意味からすると3番めのヘッダーファイル定義での対応方法が良いと思います。


ではまた〜

0 件のコメント:

コメントを投稿