[Mac][iOS] Static Library (7) カテゴリを使う場合の注意点 "-ObjC" と "-all_load"

2010年11月24日水曜日 | Published in | 0 コメント

このエントリーをはてなブックマークに追加

[前回] Cocoaの日々: [iOS] Static Library (6) OCUnitで単体テスト

カテゴリが定義されている Static Library を使う場合、リンカフラグに "-ObjC" と "all_load" を設定する必要がある。リンカフラグを設定しない場合 "selector not recognized" 例外が発生しクラッシュする。
[49296:207] -[NSCFString extString]: unrecognized selector sent to instance 0x3044
[49296:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException',
 reason: '-[NSCFString extString]: unrecognized selector sent to instance 0x3044'
*** Call stack at first throw:
このことは下記のQ&Aで解説されている。
この Q&A によればこの問題は UNIXの Static library実装 と Objective-C の動的な性質の違いによって引き起こされるとのこと。この問題を回避する為にリンカフラグに "-ObjC" オプションを追加する。

リンカフラグは、ターゲットの情報を開きビルドタブの「他のリンクフラグ」に設定する。
なお Mac OS X の64bit環境および iOS ではリンカにバグがあり、"-ObjC" フラグを指定してもカテゴリを含む Static Library のロードが働かない。これを回避する為に "-all_load" または "-force_load" フラグを使う。

"-all_load" フラグはリンカに全オブジェクトファイルのロードを指示する。"-force_load" は Xcode 3.2 から導入されたフラグで、オブジェクトファイル毎にロードを指示することができる。このフラグはオブジェクトファイルへのパスを引数に取る。


Duplicate Symbol 問題


[iPhone][Objective-C] staticライブラリにカテゴリを含む際に気をつけること によれば "-all_load" フラグも万能というわけではなく libtool のバグが原因で "Duplicate symbol" エラーを引き起こすケースがあるとのこと。この問題を回避するにはちょっとしたトリックを施すと良いらしい。以下、引用。
具体的には、以下のように関係ないクラスの宣言を.mの先頭の方に付加すればOK。「FIXCATEGORYBUG_NSSTRING_SAMPLE」は他と名前の衝突が無ければ何でもよいです。
  • NSString+Sample.m
@interface FIXCATEGORYBUG_NSSTRING_SAMPLE @end
@implementation FIXCATEGORYBUG_NSSTRING_SAMPLE @end

@implementation NSString (Sample)
 .
 .
 .
@end
この現象は確認できていないので今のところ何ともいえないがエラーが出た時に参考になりそうだ。


参考情報


IPHONE - Objective-C categories in static library - efreedom

use force_load - Three20 | Google グループ

Responses

Leave a Response

人気の投稿(過去 30日間)