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番めのヘッダーファイル定義での対応方法が良いと思います。


ではまた〜

2016年10月4日火曜日

macOS Sierra非互換:「表示」メニューに「タブバーを表示」項目が自動的に追加される(非表示化対応)

<非互換項目>

  • アプリメニューに「表示」メニューが存在すると自動的に「タブバーを表示」項目が追加表示される。


<状況・対応方法>

  • Sierra用にビルドしただけで自動的に「タブバーを表示」項目が追加され、選択するとタブ表示される機能が実装されています。
  • ゲームアプリですので当然ながら複数ドキュメント画面を開く様な機能はありませんので、「タブバーを表示」項目は表示して欲しくない。
  • 画面インタフェース定義ファイル(xibファイル)とかInfo.plist設定に「タブバーを表示」自動追加を無効化できるプロパティが無いか調べましたが、それらしい設定項目は発見できず。(xibファイルに設定あり:「追記」参照)
  • いろいろと調査した結果、下記のコード対応で「タブバーを表示」項目の自動追加を無効化する事が出来ました。(アプリ起動後の初期処理内にコード記述)


    // メニュー:タブバー非表示
    if ([NSWindow respondsToSelector:@selector(allowsAutomaticWindowTabbing)]) {
        NSWindow.allowsAutomaticWindowTabbing = NO;
    }


<追記>

  • 上記タブバー非表示のコード内容からNSWindowクラスのプロパティっぽかったので、xibエディタでWindowプロパティを再度確認すると「Tabbing Mode」があり、初期値は「Automatic」になっています。
  • 多分、この設定を変えればコード記述ではなく設定で変更可能と思われますが、Sierra以前のmacOSへの対応のため今回はコード記述にて対応しました。
xibファイル:Window設定

ではまた〜