0

我有一个非弧项目。我正在尝试使用 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:

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

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

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

4

1 回答 1

1

就块和内存管理而言,您所展示的一切似乎都还可以。它一定是别的东西。

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

于 2012-11-14T21:16:26.350 回答