det*_*zed 12 c++ objective-c ios objective-c-blocks
我有一个正在后台线程上执行的方法.从那个方法我试图dispatch_async
在主线程上的块.该块使用本地C++对象,该对象应该根据Apple参考进行复制.我得到了一个分段错误,从跟踪中我看到一些非常粗略的事情正在发生.这是我的代码的简化版本.
struct A
{
A() { printf("0x%08x: A::A()\n", this); }
A(A const &that) { printf("0x%08x: A::A(A const &%p)\n", this, &that); }
~A() { printf("0x%08x: A::~A()\n", this); }
void p() const { printf("0x%08x: A::p()\n", this); }
};
- (void)runs_on_a_background_thread
{
A a;
a.p();
dispatch_async(dispatch_get_main_queue(), ^{
printf("block begins\n");
a.p();
printf("block ends\n");
});
}
Run Code Online (Sandbox Code Playgroud)
这是输出:
0xbfffc2af: A::A()
0xbfffc2af: A::p()
0xbfffc2a8: A::A(A const &0xbfffc2af)
0x057ae6b4: A::A(A const &0xbfffc2a8)
0xbfffc2a8: A::~A()
0xbfffc2af: A::~A()
0xbfffdfcf: A::A(A const &0x57ae6b4)
0xbfffdfcf: A::~A()
block begins
0xbfffdfcf: A::p()
block ends
0x057ae6b4: A::~A()
Run Code Online (Sandbox Code Playgroud)
有两件事我不明白.第一个是为什么当它到达0xbfffdfcf: A::p()
该对象上的析构函数时已经被调用了.
我正在努力的第二件事是为什么有这么多的复制构造函数被调用.我期待一个.当a
创建要由块捕获的副本时,应该发生这种情况.
我正在使用Xcode 3.2.5和GCC.我在模拟器和设备上遇到相同的行为.
我刚刚在LLVM 3.0上测试了这个.
0xb024ee18: A::A()
0xb024ee18: A::p()
0xb024ee04: A::A(A const &0xb024ee18)
0x06869364: A::A(A const &0xb024ee04)
0xb024ee04: A::~A()
0xb024ee18: A::~A()
block begins
0x06869364: A::p()
block ends
0x06869364: A::~A()
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,在这种情况下,析构函数会被恰当地调用,我会将其归结为您正在使用的极其过时的编译器中的编译器错误.
这个例子中的副本似乎符合我的期望.该块在捕获时将基于堆栈的对象复制到块中.然后当块从堆栈复制到堆时再次出现.