0

我有一個非弧項目。我試圖使用dispatch_async從服務器獲取數據並將其保存在sqlite中。 dispatch_async在具有回調的方法內發生。在調用該方法時,應用程序會崩潰,並導致訪問不良。這裏是我如何實現代碼。使用塊調度異步exc_bad_access非ARC項目

- (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: 我試過下面給出的示例答案,它仍然崩潰。

我想複製它然後autorelease它。它經常崩潰,但尼特。我要檢查內存泄漏。我會報告。

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

請發佈一個stacktrace。 – trojanfoe

回答

1

您所展示的一切在塊和內存管理方面似乎都沒有問題。它一定是別的東西。

我注意到你傳入一個C字符串(字符指針receivedData),你沒有使用。如果你沒有向我們展示真正的代碼,並且實際上在塊中使用了receivedData變量,那麼這可能是一個問題,因爲該塊只是簡單地捕獲字符指針,但不管理字符串後面的字符串的內存指針(它不是一個Objective-C對象)。因此,C字符串可能僅在調用作用域中有效(在異步操作之前),並且在異步操作運行時不再有效。你的聲明在strlen上崩潰,支持某個C字符串出現問題的想法。您應該嘗試使用NSString對象,因爲作爲對象,它們可以通過塊進行適當的內存管理。

+0

我剛剛在深夜醒來時也有同樣的想法。抱歉不能顯示真實的代碼。我害怕僱主不會喜歡它。另一個人用c/C++編寫所有東西。無論如何,我會稍後嘗試使用nsstring,但現在XML解析器完全在使用receivedData的C++中。這真的是痛苦的脖子。謝謝您的幫助。我會在早上報告。 –