11

MacOS には、ARC を実装し、ユーザーの設定に応じて 10 秒または 15 秒ごとにサーバーにいくつかのリクエストを送信するエージェントがあり、ほぼ 1 年間問題なく動作していましたが、ほんの数週間前にアプリケーションがクラッシュしました。 1 台のコンピューターで、特に次の行で、Bad access エラーが発生しました。

[NSURLConnection sendSynchronousRequest:request returningResponse:&responseCode error:&error];

問題を引き起こしているマシンの Mac OS X バージョンは 10.7.5 ですが、同じ OS バージョンの他のコンピュータでは問題なく動作しています。

作業を行う必要があるため、同期リクエストを使用していますが、呼び出しを非同期にするのに時間を費やしましたが、問題は解決しません。

そこで、他の投稿を見て、キャッシュ ポリシーを追加しました。キャッシュ要求の問題を回避するため。アプリケーションはより良く実行されますが、通常は 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;
}

任意の提案をいただければ幸いです。

4

1 に答える 1

1

まず、コードは私には良さそうです。

アプリがメモリをリークしないように、インストルメントでメモリ プロファイルを作成します。このコードはアプリで最も呼び出されるコードである可能性が高いため、アプリの状態が破損すると、そこでクラッシュする可能性も高くなります。また、同じ理由でハードウェアをテストする必要があります ( http://osxdaily.com/2011/05/03/memtest-mac-ram-test/ )。

また、コードは簡単に分離できるため、URL またはいくつかのパブリック URL を呼び出すだけでテスト アプリを作成できます。このアプリもクラッシュさせることができれば、Apple にバグを報告することができます。

于 2013-09-15T08:44:01.290 に答える