Приращение `static int` вызывает SIGSEGV SEGV_ACCERR
Я отлаживаю сбой, о котором сообщают как:
Exception Type: SIGSEGV
Exception Codes: SEGV_ACCERR
Авария происходит на линии, которая делает numberOfFails++
,
Приложение использует ASIHTTP
, Я лично очень предпочитаю использовать NSURLConnection
, Я никогда не буду автоматически повторять запрос NSURLConnection
если он потерпел неудачу, потому что я никогда не видел, чтобы он потерпел неудачу, когда не должен Я бы предпочел просто дать пользовательскому интерфейсу кнопку обновления или показать UIAlertView
с кнопкой, чтобы попробовать еще раз или что-то в этом роде.
Во всяком случае, чтобы сотрудничать с другими членами команды, я хочу исправить эту проблему без замены ASIHTTP
с NSURLConnection
теперь.
Запрос запускается с чем-то вроде:
- (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
(Неверные разрешения для сопоставленного объекта).
Мысли?
1 ответ
Вероятно, проблема не имеет ничего общего с вашей статической переменной.
Есть ли requestFailed:
выполнить в основном потоке или в фоновом потоке?
Если это в фоновом потоке, вам нужно использовать performSelectorOnMainThread:withObject:
,
Если он находится в главном потоке, вам может потребоваться пройти через цикл запуска перед выполнением нового HTTP-запроса. Для этого используйте performSelector:withObject:afterDelay:
и передайте '0.0' в качестве задержки.
Вы заметите, что оба этих метода допускают только один параметр метода. Как правило, вы передаете свои параметры в NSDictionary
вместо того, чтобы пытаться разобрать количество параметров заранее, как вы делаете.