增加`static int`会导致SIGSEGV SEGV_ACCERR [英] Incrementing `static int` causes SIGSEGV SEGV_ACCERR
问题描述
我正在调试崩溃报告为:
异常类型:SIGSEGV
异常代码:SEGV_ACCERR
崩溃发生在 numberOfFails ++
。
应用程序使用 ASIHTTP
。我个人更喜欢使用 NSURLConnection
。我永远不会自动重复请求 NSURLConnection
如果失败,因为我从来没有看到它失败,当它不应该。我宁愿只给UI一个刷新按钮,或者用一个按钮显示一个 UIAlertView
,再试一次或类似的东西。
无论如何,与其他团队成员合作,我正在寻找解决这个问题,而不用 ASIHTTP
替换 NSURLConnection $ c $
<$ c> $ c> - (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&
不在头文件中,但此回调方法仍在调用确定:
#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:@Problemmessage:@连接到服务器时出现问题,请确保您已连接到互联网。 delegate:nil cancelButtonTitle:@OkotherButtonTitles:nil];
[alert show];
[alert release];
numberOfFails = 0;
}
}
static int numberOfFails 应该是 static NSUInteger numberOfFails
。并且,我注意到请求是以 startAsynchronous
开始的。是 static int numberOfFails
atomic?这可能是为什么我们得到错误 SEGV_ACCERR
(映射对象的权限无效)。
想法? / p>
此问题可能与您的静态变量无关。
requestFailed:
在主线程或后台线程中执行吗?
如果是在后台线程,你需要使用 performSelectorOnMainThread:withObject:
。
如果它在主线程上,您可能需要在执行新的HTTP请求之前通过runloop。为此,使用 performSelector:withObject:afterDelay:
,并传递'0.0'作为延迟。
将注意到这两种方法只允许一个方法参数。通常,你在 NSDictionary
中传递你的参数,而不是像你一样尝试解析参数的数量。
I'm debugging a crash reported as:
Exception Type: SIGSEGV
Exception Codes: SEGV_ACCERR
The crash is happening on the line that does numberOfFails++
.
The app uses ASIHTTP
. I personally much prefer using NSURLConnection
. I'd never automatically repeat a request for NSURLConnection
if it failed because I've never seen it fail when it shouldn't. I'd rather just give the UI a refresh button or show a UIAlertView
with a button to try again or something like that.
Anyway, to cooperate with other team members, I'm looking to fix this issue without replacing ASIHTTP
with NSURLConnection
for now.
The request is being started with something like:
- (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];
}
One thing I noticed is : <ASIHTTPRequestDelegate>
is not in the header file, but this callback method is still being called 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;
}
}
Also, I think that static int numberOfFails
should be static NSUInteger numberOfFails
. And, I noticed that the request is started with startAsynchronous
. Is static int numberOfFails
atomic? That may be why we're getting the error SEGV_ACCERR
(Invalid permissions for mapped object).
Thoughts?
The problem likely has nothing to do with your static variable.
Does requestFailed:
execute on the main thread, or in a background thread?
If it's on a background thread, you'll need to use performSelectorOnMainThread:withObject:
.
If it's on the main thread, you may need to take a pass through the runloop before executing a new HTTP request. To do that, use performSelector:withObject:afterDelay:
, and pass '0.0' as the delay.
You'll notice that both those methods allow only a single method parameter. Typically, you pass your parameters in a NSDictionary
rather than try to parse out the number of parameters beforehand, like you're doing.
这篇关于增加`static int`会导致SIGSEGV SEGV_ACCERR的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!