更新:これは iOS 6.1 DP3 SDK で修正されました。
デフォルトのリリース ビルド構成を使用して ARC でビルドすると、use-after-deallocated クラッシュが発生することを突き止めました (デバッグは正常に機能しているようです)。この問題は、非定数条件で if スコープ内にオブジェクトを作成し、それをスコープ外から変数に割り当ててから、Objective-C 配列または辞書リテラルを使用してのみ変数を参照するときに発生します。
これは、私が見つけた再現可能な最小のケースです。
void test(BOOL arg)
{
id obj = nil;
if (arg) {
obj = [NSObject new];
}
// obj already deallocated here
@[obj];
// but using NSArray works
//[NSArray arrayWithObject:obj];
// @[obj] works if obj is referenced i.e. by NSLog print out
//NSLog(@"%@", obj);
}
int main(int argc, const char * argv[])
{
@autoreleasepool {
test(YES);
}
return 0;
}
ゾンビ オブジェクトを有効にしてこれをビルドして実行すると、次のエラー メッセージが表示されます。
-[NSObject retain]: message sent to deallocated instance 0x100109100
コードでコメントしたように、 withまたは using insteadobj
のように、他の方法で参照されている場合は正常に動作します。オブジェクトが ARC とスコープでどのように解放されるかを誤解していますか、それとも LLVM または Clang の最適化バグですか?NSLog
NSArray
Xcode 4.5.2 を clang バージョン 4.1 (tags/Apple/clang-421.11.66) (LLVM 3.1svn ベース) で使用しています。iOS シミュレーターおよび Mac OS X 用の x86 64 ビット用にビルドするときに再現できます。iPhone でリリース ビルドを実行したときに問題が最初に見つかったのと同じ問題が、ARM 用にビルドするときに発生することは間違いありません。
Apple にバグ レポートを提出し、オープン レーダー レポートを作成しました。
もしあれば、何が欠けていますか?
更新、さらにいくつかの実験を行いました:
Gabro が指摘したように、コンパイラはステートメントに変換される@[]
ため、[NSArray arrayWithObjects:count:]
いくつかのテストを行いました。
// works
id a[] = {obj};
[NSArray arrayWithObjects:a count:1];
// does not work
const id *b = (id[]){obj};
[NSArray arrayWithObjects:b count:1];
// does not work
[NSArray arrayWithObjects:(id[]){obj} count:1];
私の推測では、これは ARC と無名 C 配列を組み合わせたときに発生します。