2012-04-23 6 views
0

すべてのネットワーク通信にASIHttpRequestを使用するプロジェクトを継承しました。私が使用している特定のバージョンが不明です。私が知ることができるのは、.hファイルから、特定のファイルの最も古い作成日が17/08/10(ASIDataDecompressor)であることです。多くのリークを引き起こす非同期要求の実装

完了ブロックと失敗ブロックを使用しています。何らかの理由で、障害ブロックが頻繁に起動されることがあります。これは、サーバーが応答できない場合にのみ実際に発生する必要があります。ログが正常に表示され、エラーが発生したときにサーバーの問題が発生しているという通知(Airbrake)が届いていないため、今はサーバーが正常であるという前提で前進しています。犯人。

私はInstruments(Leaks)を通じてアプリケーションを実行することに決めました。私が要求を強制的に強制すると、すぐに27個のリークが作成されることを知りました。私はインストゥルメンツをうまく乗り越える方法がわからないので、今私が持っている情報をどうしたらいいのか分かりません。

私は何か目立つものがあるかどうか確認するために私のコードを掲示すると思った。 viewDidLoadで

、このコードは

[[MyAPI sharedAPI] getAllHighlights:pageNumber:perPage onSuccess:^(NSString *receivedString,NSString *responseCode) { 
     [self getResults:receivedString]; 
     if(![responseCode isEqualToString:@"Success"]) { 
      [self hideProgressView]; 
      appDelegate.isDiscover_RefreshTime=YES;     
      [[MyAPI sharedAPI] showAlert:responseCode]; 
     } else { 
      NSString *[email protected]"Discover_Highlights_Loaded Page_"; 
      strLogEvent=[strLogEvent stringByAppendingFormat:@"%i",intPageNumber]; 
      [FlurryAnalytics logEvent:strLogEvent timed:YES]; 
     } 
    } onFail:^(ASIFormDataRequest *request) { 
     NSDictionary *parameters = [[MyAPI sharedAPI] prepareFailedRequestData:request file:@"Discover" method:_cmd]; 
     [FlurryAnalytics logEvent:@"Unable_to_Connect_to_Server" withParameters:parameters timed:true]; 
     [self hideProgressView]; 
     appDelegate.isDiscover_RefreshTime=YES; 

     [[AfarAPI sharedAPI] showAlert:@"Unable to Connect to Server."]; 
     [tblHighlightsGrid reloadData]; 
     [tblListHighlights reloadData]; 

}]; 

を実行され、これらのtypedefは、APIシングルトンの先頭で定義されています:

typedef void (^ASIBasicBlockWrapper)(NSString *responseString,NSString *responseCode); 
typedef void (^ASIBasicBlockWrapperFail)(ASIFormDataRequest *request); 

MyAPISingleton番号のgetAllHighlightsは...

- (void)getAllHighlights:(NSString *)pageNumber:(NSString *)perPage onSuccess:(ASIBasicBlockWrapper)cb1 onFail:(ASIBasicBlockWrapperFail)cb2{ 
    NSString *access_token= [[NSUserDefaults standardUserDefaults] objectForKey:@"access_token"]; 

    NSString *url = [baseURL stringByAppendingFormat:AFAR_GET_ALL_HIGHLIGHTS_ENDPOINT, pageNumber,perPage]; 
    if (access_token) { url = [url stringByAppendingFormat:ACCESS_TOKEN, access_token]; } 

    __block ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:url]]; 
    [request setRequestMethod:@"GET"]; 
    [request setDelegate:self]; 
    [self executeAsynchronousRequest:request onSuccess:cb1 onFail:cb2]; 
} 

最後に、MyAPI#はAsynchronousRequestを実行します:

なぜ27個のリークが作成されたのかが目立ちますか?

+0

あなたは静的アナライザを実行しようとしたことがあり:

ここに私の漏れがexecuteAsyncRequestのフリーな実装ですか?漏れを見つけるための最初の停止。 – Martin

+0

私はやった、と私は明らかです(残念ながら)。それは簡単だったと願います。:) – djibouti33

+0

機器のリークを追跡するのに便利なのは、コールツリーに切り替えて、サイドバーの* Hide System Libraries *をチェックすることです。http://cl.ly/3r3P1X1s0b0M1X1j3t14 – keegan3d

答えて

0

私はこれを理解しました。

ASIHttpRequest Documentationあなたは__blockストレージメカニズムを使用してリクエストオブジェクトを指定する必要があるという事実について非常に明確である:私たちは要求を宣言するとき

は__block修飾子の使用に注意してください、これは重要です!要求を保持しないようブロックに指示します。要求が常にブロックを保持するため、保持サイクルを防止する上で重要です。

getAllHighlights()では、私はそれをやっていますが、次にリクエストオブジェクトを別のメソッド(executeAsyncRequest)の引数として送信しています。 __blockストレージタイプはローカル変数でのみ宣言できます。したがって、メソッドシグネチャのrequestは通常のASIFormDataRequestに入力されているため、__blockステータスが失われたように見えます。

ブロックで使用する前に、そのトリックは(それが技術的に正確であるかどうかはわかりませんが)引数をキャストすることです。

- (void) executeAsyncRequest:(ASIFormDataRequest *)request onSuccess:(ASIBasicBlockWrapper)cb1 onFail:(ASIBasicBlockWrapperFail)cb2 
{ 
    // this is the important part. now we just need to make sure 
    // to use blockSafeRequest _inside_ our blocks 
    __block ASIFormDataRequest *blockSafeRequest = request; 

    [request setCompletionBlock: ^{ 
     int statusCode = [blockSafeRequest responseStatusCode]; 
     NSString *statusMessage = [self statusErrorMessage:statusCode]; 
     cb1([blockSafeRequest responseString],statusMessage); 
    }]; 

    [request setFailedBlock: ^{ 
     cb2(blockSafeRequest); 
    }]; 

    [request startAsynchronous];  
} 
関連する問題