Mac OS X代理上同步请求的随机错误

avm*_*cio 11 macos objective-c nsurlconnection

在MacOS上,我们有一个实现ARC的代理,它将根据用户的设置每10或15秒向服务器发出一些请求,并且在将近一年的时间内没有任何问题,几周前应用程序崩溃了在一台具有错误访问错误的计算机中,特别是在此行上:

[NSURLConnection sendSynchronousRequest:request returningResponse:&responseCode error:&error];
Run Code Online (Sandbox Code Playgroud)

导致问题的机器的Mac OS X版本是10.7.5,但是在具有相同OS版本的其他计算机中工作正常.

我们正在使用同步请求,因为这是我们需要做的工作,但是我们花了一些时间使调用异步,但问题仍然存在.

因此,在查看其他帖子后,我们添加了一个缓存策略:[request setCachePolicy:NSURLRequestReloadIgnoringCacheData]; 避免缓存请求的任何问题.应用程序确实运行得更好,但在15到20次迭代之间崩溃之前,通常会在1500到1800次迭代(30-40分钟)之间崩溃.

通过查看堆栈溢出中的另一个问题,我们尝试使用ASIHTTPRequest修复此问题,但问题再次发生(它可能会在迭代#2或#123x ......中崩溃).

在出现错误之前,请求始终正常工作,我们正在获取数据并能够正常使用它.

启用NSZombieEnabled选项后,当应用程序崩溃时,我们没有收到任何消息,因为错误指向上面的特定行,因此try/catch块对我们不起作用;

[NSURLConnection sendSynchronousRequest:request returningResponse:&responseCode error:&error]
Run Code Online (Sandbox Code Playgroud)

这是我们使用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];
Run Code Online (Sandbox Code Playgroud)

这是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;
}
Run Code Online (Sandbox Code Playgroud)

任何建议将不胜感激.

sof*_*der 1

首先,代码对我来说看起来不错。

我会使用仪器进行内存配置文件,以确保应用程序不会泄漏内存。由于此代码可能是应用程序中调用次数最多的代码,因此如果应用程序状态损坏,它也更有可能崩溃。此外,出于同样的原因,您应该测试您的硬件(http://osxdaily.com/2011/05/03/memtest-mac-ram-test/)。

此外,您的代码很容易隔离,因此您只需调用您的 URL 甚至一些公共 URL 即可创建测试应用程序。如果你也能让这个应用程序崩溃,那么你就可以向 Apple 提交错误。