2011-05-30 33 views
1

我調試報告崩潰:遞增`靜態int`導致SIGSEGV SEGV_ACCERR

Exception Type: SIGSEGV 
Exception Codes: SEGV_ACCERR 

的崩潰是發生在,做numberOfFails++行。

應用程序使用ASIHTTP。我個人更喜歡使用NSURLConnection。如果失敗,我永遠不會自動重複請求NSURLConnection,因爲我從來沒有見過它失敗時,它不應該。我寧願只給UI的刷新按鈕,或顯示UIAlertView一個按鈕再試一次或類似的東西。

無論如何,爲了與其他團隊成員合作,我期待着解決這個問題,而不是現在用NSURLConnection來代替ASIHTTP

請求正在啓動的東西,如:

- (void)getResources:(CLLocation *)location withQuery:(NSString *)query { 
    NSURL *url = [NSURL URLWithString:[NSString stringWithString:@"https://example.com/"]]; 
    self.resourcesAPIRequest = [ASIFormDataRequest requestWithURL:url]; 
    [resourcesAPIRequest setPostValue:[Model instance].oauth_token forKey:@"oauth_token"]; 
    [resourcesAPIRequest setPostValue:[[NSNumber numberWithDouble:location.coordinate.latitude] stringValue] forKey:@"latitude"]; 
    [resourcesAPIRequest setPostValue:[[NSNumber numberWithDouble:location.coordinate.longitude] stringValue] forKey:@"longitude"]; 
    [resourcesAPIRequest setPostValue:query forKey:@"query"]; 
    [resourcesAPIRequest setDelegate:self]; 
    [resourcesAPIRequest setDidFinishSelector:@selector(resourcesAPIReturned:)]; 
    resourcesAPIRequest.userInfo = [NSDictionary dictionaryWithObjectsAndKeys:NSStringFromSelector(@selector(getResources:withQuery:)), @"repeatSelector", location, @"argument1", query, @"argument2", nil]; 
    [resourcesAPIRequest startAsynchronous]; 
} 

有一件事我注意到的是: <ASIHTTPRequestDelegate>是不是在頭文件,但這個回調方法仍然被稱爲OK:

#define maximumNumberOfFails 50 

- (void)requestFailed:(ASIFormDataRequest *)request { 
    static int numberOfFails = 0; 

    if (numberOfFails < maximumNumberOfFails) { 
     [NSThread sleepForTimeInterval:sleepTimeInSeconds]; 
     if ([request.userInfo objectForKey:@"argument2"]) { 
      [self performSelector:NSSelectorFromString([request.userInfo objectForKey:@"repeatSelector"]) withObject:[request.userInfo objectForKey:@"argument1"] withObject:[request.userInfo objectForKey:@"argument2"]]; 
     } else if ([request.userInfo objectForKey:@"argument1"]) { 
      [self performSelector:NSSelectorFromString([request.userInfo objectForKey:@"repeatSelector"]) withObject:[request.userInfo objectForKey:@"argument1"]]; 
     } else { 
      [self performSelector:NSSelectorFromString([request.userInfo objectForKey:@"repeatSelector"])]; 
     } 
     numberOfFails++; 
    } else { 
     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Problem" message:@"There was a problem connecting to the servers. Please make sure you have an Internet connection." delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil]; 
     [alert show]; 
     [alert release]; 
     numberOfFails = 0; 
    } 
} 

另外,我認爲static int numberOfFails應該是static NSUInteger numberOfFails。而且,我注意到請求從startAsynchronous開始。是static int numberOfFails原子?這可能是爲什麼我們得到錯誤SEGV_ACCERR(映射對象的無效權限)。

想法?

回答

3

問題可能無關,與你的靜態變量。

是否requestFailed:執行主線程上,或者在後臺線程?

如果它是在後臺線程,你需要使用performSelectorOnMainThread:withObject:

如果它在主線程上,則可能需要在執行新的HTTP請求之前先通過runloop。要做到這一點,請使用performSelector:withObject:afterDelay:,並將'0.0'作爲延遲。

你會注意到這兩種方法只允許一個方法參數。通常,您將參數傳遞給NSDictionary,而不是嘗試事先解析出參數的數量,就像您正在做的那樣。