在 MacOS 上,我们有一个实现 ARC 的代理,它会根据用户的设置每 10 或 15 秒向服务器发出一些请求,并且工作了将近一年没有任何问题,而就在几周前,应用程序崩溃了在一台出现错误访问错误的计算机中,特别是在这一行:
[NSURLConnection sendSynchronousRequest:request returningResponse:&responseCode error:&error];
导致问题的机器的 Mac OS X 版本是 10.7.5,但是在具有相同操作系统版本的其他计算机上运行正常。
我们正在使用同步请求,因为这是我们需要做的工作,但是我们花了一些时间使调用异步但问题仍然存在。
因此,在查看其他帖子后,我们添加了一个缓存策略:[request setCachePolicy: NSURLRequestReloadIgnoringCacheData]; 以避免缓存请求出现任何问题。该应用程序确实运行得更好,但通常在 1500 - 1800 次迭代(30-40 分钟)之间仍然崩溃,然后在 15 或 20 次迭代之间崩溃。
通过查看堆栈溢出中的另一个问题,我们尝试使用 ASIHTTPRequest 解决此问题,但问题再次随机发生(它也可能在迭代 #2 或 #123x 中崩溃......)。
在错误出现之前,请求始终正常工作,我们正在获取数据并能够正常使用它。
启用 NSZombieEnabled 选项后,当应用程序崩溃时,我们不会收到任何消息,try/catch 块对我们也不起作用,因为错误指向上方的特定行;
[NSURLConnection sendSynchronousRequest:request returningResponse:&responseCode error:&error]
这是我们必须使用 NSURLConnection 发出请求的代码:
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]
init]; [request setHTTPMethod:@"GET"]; [request setURL:[NSURL
URLWithString:url]]; [request setTimeoutInterval: TIMEOUT];
[request setCachePolicy: NSURLRequestReloadIgnoringCacheData];
NSString *authenticationHeader = [NSString
stringWithFormat:@"Basic %@", credentials]; [request
addValue:authenticationHeader
forHTTPHeaderField:@"Authorization"];
NSError *error = nil; NSHTTPURLResponse *responseCode = nil;
NSData *responseData = nil; responseData = [NSURLConnection
sendSynchronousRequest:request returningResponse:&responseCode
error:&error];
if([responseCode statusCode] != 200){ *hasError =[NSString
stringWithFormat: @"Error getting %@, HTTP status code %li",
[responseCode statusCode]]; return @"";
}
}
return [[NSString alloc] initWithData:responseData
encoding:NSUTF8StringEncoding];
这是 ASIHttpRequest 的代码:
(NSString *)getDataFromURL: (NSString *)urlString withB64Credentials:(NSString *)credentials error:(NSString **)hasError
{
NSString *response = @"";
NSURL *url = [NSURL URLWithString:urlString];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setCachePolicy:ASIDoNotReadFromCacheCachePolicy];
[request setTimeOutSeconds:TIMEOUT];
NSString *authenticationHeader = [NSString stringWithFormat:@"Basic %@", credentials];
[request addRequestHeader:@"Authorization" value:authenticationHeader];
[request startSynchronous];
NSError *error = [request error];
if (!error)
response = [request responseString];
else
NSLog(@"%@", [error description]);
return response;
}
任何建议将不胜感激。