使用块exc_bad_access非ARC项目调度异步

时间:2012-11-14 15:36:21

标签: objective-c xcode objective-c-blocks grand-central-dispatch

我有一个非弧项目。我正在尝试使用dispatch_async从服务器获取数据并将其保存在sqlite中。 dispatch_async发生在带回调的方法中。在调用该方法时,应用程序崩溃与错误的访问。这是我如何实现代码。

- (void) HandleData:(const char*) receivedData WithSuccess:(void(^)(BOOL finishing))completed
{
dispatch_queue_t fetchQ = dispatch_queue_create("Refreshing", NULL);
dispatch_async(fetchQ, ^{

   [self write_data_in_sqlite]//    **<--crash happens here in the method which is called here**
    }
    dispatch_sync(dispatch_get_main_queue(), ^{
            completed(YES);
    });
});
dispatch_release(fetchQ);
}

我将该方法称为:

HandleResponse *handleResponse = [[[HandleResponse alloc] init] autorelease];
                [handleResponse HandleData:aData WithSuccess:^(BOOL finishing) {
                 if(finishing)
                 {
                 //update the UI here
                 }
                 }];

如果我删除dispatch_async然后它不会崩溃,但我的UI在写入sqlite时被阻止。

我做错了什么?

修改: 删除块并使用dipatch_async会产生相同的exc_bad_access崩溃。

编辑2: 我尝试了下面给出的示例答案,它仍然崩溃。

我想复制它然后自动释放它。它经常崩溃但仍然崩溃。我要检查内存泄漏。我会报告。

HandleResponse *handleResponse = [[[HandleResponse alloc] init] autorelease];
        [handleResponse HandleData:aData WithSuccess: [[^(BOOL finishing) {
         if(finishing)
         {
         //update the UI here
         }
         } copy] autorelease];

编辑3:

崩溃发生在strlen中,即使xml内容在xmlResopnse中也是如此。但为什么会发生这种情况而不是没有它

xmlDocPtr xml= xmlParseMemory(xmlResopnse, strlen(xmlResponse);

编辑4: 如下面的答案建议不要在调度异步中使用c对象。所以我将xmlResponse从const char *转换为nsstring,它并没有崩溃。

1 个答案:

答案 0 :(得分:1)

你所展示的所有内容在块和内存管理方面似乎都没问题。它必须是别的东西。

我注意到你传入了一个你没有使用的C字符串(char指针receivedData)。如果您没有向我们展示真实代码,并且您实际上正在使用块中的receivedData变量,那么这可能是一个问题,因为块只是捕获了char指针,但是没有管理内存指针后面的字符串(它不是Objective-C对象)。因此,C字符串可能仅在调用范围内有效(在异步操作之前),并且在异步操作运行时不再有效。你在strlen崩溃的声明支持了一些C字符串出错的想法。您应该尝试使用NSString对象,因为作为对象,它们由块正确地进行内存管理。