2

iOS SDK 6.0 で ARC を使用しています。

追跡に苦労しているメモリリークがいくつかあると確信しています。

静的アナライザーを実行した後、次の 2 つの方法に関する警告が表示されます。

+ (id<MXURLRequest>) requestWithURL:(NSURL*)url {    
  MXASIURLRequest *request = [[MXASIURLRequest alloc] init];

  [request setUrl:url];

  return request; // STATIC ANALYSER: Potential leak of an object stored into 'request' 
}

- (id)parseBody:(NSError *)error {    
  NSString *contentType = [[_request responseHeaders] objectForKey:@"Content-Type"];

  id body = nil;

  if ([contentType hasPrefix:@"application/json"] ||
      [contentType hasPrefix:@"text/json"] ||
      [contentType hasPrefix:@"application/javascript"] ||
      [contentType hasPrefix:@"text/javascript"]) {        
    body = [NSJSONSerialization JSONObjectWithData:[_request responseData] options:NSJSONReadingMutableLeaves error:&error];
  } else if ([contentType hasPrefix:@"image/"] ||
           [contentType hasPrefix:@"audio/"] ||
           [contentType hasPrefix:@"application/octet-stream"]) {        
    body = [_request responseData];
  } else {
    body = [[NSString alloc] initWithData:[_request responseData] encoding:NSUTF8StringEncoding];
  }

  return body; // STATIC ANALYSER : Potential leak of an object stored into 'body'
}

警告は次のとおりです...

Object leaked: object allocated and stored into 'request' is returned from a method
whose name ('requestWithURL:') does not start with 'copy', 'mutableCopy', 'alloc'
or 'new'.  This violates the naming convention rules given in the Memory Management 
Guide for Cocoa

Object leaked: object allocated and stored into 'body' is returned from a method
whose name ('parseBody:') does not start with 'copy', 'mutableCopy', 'alloc' or
'new'.  This violates the naming convention rules given in the Memory Management
Guide for Cocoa

ここで私が間違ったことを誰かが見ることができますか? これらの警告は正当なものですか、それとも無視できますか? 私には、これらの方法は、ARC が自動参照カウントを処理できるように有効に見えます。

どんな助けでも大歓迎です。

4

1 に答える 1

8

ARC は、これがコンパイルされるファイルに対して、またはプロジェクト全体に対して明らかにオフになっています。静的アナライザーは、ARC がオフになっている場合にのみこの問題について不平を言うので、それを念頭に置いてさらに詳しく説明します。

コンパイラが参照する Cocoa メモリ管理ガイドラインでは、通常の状況 (「init」、「copy」、「mutableCopy」、および「new」) でコンストラクターから非自動解放オブジェクトを返すメソッドの厳密なセットのみが許可されています。パターンに注意してください。

便利なコンストラクターでオブジェクトを割り当ててから呼び出し元に渡すため、作成したので、それを所有しているのはあなたです。Cocoa があなたに求めているのは、戻り値の最後に autorelease を追加して、新しく構築されたオブジェクトへの参照を保持するのが呼び出し元の仕事になるようにすることです。

+ (id<MXURLRequest>) requestWithURL:(NSURL*)url {
    MXASIURLRequest *request = [[MXASIURLRequest alloc] init]; +1, we own it

    [request setUrl:url];

    return [request autorelease]; // +0, it's the caller's problem now
}

最後の方法については、Cocoa は、メモリに関して一貫性がないと不平を言っています。このメソッドは、コンストラクターと便利機能が混在しているため、保持カウントが +1 または +0 のオブジェクトを返す可能性があります。説明する:

- (id)parseBody:(NSError *)error {    
  NSString *contentType = [[_request responseHeaders] objectForKey:@"Content-Type"];

  id body = nil;

  if ([contentType hasPrefix:@"application/json"] ||
      [contentType hasPrefix:@"text/json"] ||
      [contentType hasPrefix:@"application/javascript"] ||
      [contentType hasPrefix:@"text/javascript"]) {        
    body = [NSJSONSerialization JSONObjectWithData:[_request responseData] options:NSJSONReadingMutableLeaves error:&error]; //returns +0
  } else if ([contentType hasPrefix:@"image/"] ||
           [contentType hasPrefix:@"audio/"] ||
           [contentType hasPrefix:@"application/octet-stream"]) {        
    body = [_request responseData]; //potentially returns +1
  } else {
    body = [[NSString alloc] initWithData:[_request responseData] encoding:NSUTF8StringEncoding]; //returns +1
  }

  return body; // STATIC ANALYSER : Potential leak of an object stored into 'body'
}

アナライザーは一貫性を求めています: コンストラクターのみを使用するか、一貫して自動解放します。

于 2013-02-13T16:52:37.347 に答える