ARC 使用時の performSelector のワーニング

ARC を使用している場合、SEL 型の変数を指定して performSelector: を実行すると、”PerformSelector may cause a leak because its selector is unknown” というワーニングが出てくる、それについてのメモ。

ARC と performSelector:

ARC は、retain や release を明示的におこなわなくてよく便利だが、その正しい動作のためにはメソッドの名前付け規則が重要となっている。これは、プロパティに new で始まるものを作成してはならないという規則からうかがえる。(new で始まるプロバティを作成すると、その getter として new で始まるメソッドが作成される。一方、new で始まるメソッドが返すオブジェクトの所有権=解放の責任は呼び出し側になるので、呼び出し側の肩代わりする責任のある ARC にとって、どう管理すべきかわからない不透明な状況では責任が取れない。)

SEL 型の変数を指定して performSelector: を実行するということは、返されるオブジェクトの所有権をどのように判断すべきか、少なくともコンパイル時には判明しない。(このワーニングがでたものは、NSOperationQueue や NSOperation をラッピングして使いやすくするライブラリを作成しているときで、こうなるといくらコードをたどっても実行時にしかわからない。)よって、コンパイラとしてはワーニングを出すことでしか責任を果たせないことは納得できる。

ワーニングの回避

ワーニングが気持ち悪いというより、ワーニングを含めてコンパイラから何も言われないようにしてこそコードの完成とすべき方針からはなんとかしたい。これは、ワーニングであってもコードで対応、コードで対応できずワーニングが出ることがやむを得ない場合(今回のケース)には “ワーニングそのものでを全体にわたってではなく” その部分のワーニングをサプレスするというもので、多くのワーニングを放置しておれば、本来対応すべきワーニングが出ても、もともと多くのワーニングが出ていてそれにまぎれてしまって見逃すと、それが問題の根源となりかねないということからである。(コードの世界のヒヤリハット?!)

局所的にワーニングを抑える pragma は用意されていないようないだが、ワーニングそのものを pragma で抑えることは可能のようである。

SEL startedAction;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
    [self performSelector:startedAction];
#pragma clang diagnostic pop

確認バージョン

  • Xcode Version 4.6.3 (4H1503)
カテゴリー: 開発 Tips (31): Objective-C タグ: パーマリンク

コメントは停止中です。