Objective-CブロックのスタックにC++クラスのインスタンスをキャプチャしようとすると、私はいくつかの奇妙な動作が見られます。一つは、ローカル変数test
がブロックblk
で撮影しますと、それは一貫性のある状態を持っていることを期待スタック上のC++クラスインスタンスをObjective-Cブロックで取得できますか?
#import <Foundation/Foundation.h>
#include <stdio.h>
struct Test
{
Test() : flag(0) { printf("%p default constructor\n", this); }
Test(const Test& other) : flag(0) { printf("%p copy constructor\n", this); }
~Test() { flag = 1; printf("%p destructor\n", this); }
int flag;
};
int main(int argc, char **argv)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
Test test;
void (^blk)(void) = ^(void)
{
printf("flag=%d (test=%p)\n", test.flag, &test);
};
printf("about to call blk\n");
blk();
[pool release];
return 0;
}
:次のコードを考えてみましょう。しかし、そうではありません。このコードの出力は次のとおりです。だから、
0x7fff5fbff650 default constructor
0x7fff5fbff630 copy constructor
about to call blk
0x7fff5fbff5d0 copy constructor
0x7fff5fbff5d0 destructor
flag=1 (test=0x7fff5fbff5d0)
0x7fff5fbff630 destructor
0x7fff5fbff650 destructor
ブロックは、そのデストラクタが呼ばれてきたことを見ているローカルTest
インスタンス!あなたがやっていることは、未定義の振る舞いです。例えば、デストラクタがポインタをNULLに設定せずに削除した場合など、クラッシュする可能性があります。
C++クラスのインスタンス変数はObjective-Cブロックでサポートされていますか? Block Programming Topicsセクションの「C++オブジェクト」は、それらが存在しているように見えますが、明らかにここでは機能していません。これはコンパイラ/ランタイムのバグですか?これはMac OS X v10.6.8上のGCC 4.2.1、Apple build 5666でテストされました。
Sweet - あなたは正しい:-)ブロック外で宣言されたstd :: mapの要素にアクセスするとき、BAD_ACCESS例外が発生しました。 [BlockLanguageSpec](http://clang.llvm.org/docs/BlockLanguageSpec.txt)は、 "スタックローカルオブジェクトはコピーコンストラクタを介してブロックにコピーされる"と述べているので、動作するはずです。バグ。 LLVM 3.0に切り替えると問題が解決しました。 – Sebastian