1

私はARCに関連する記事を読んでいました.以下はセクションです:

ARC はまた、Objective-C 言語の命名規則を利用して、返されたオブジェクトの所有権を推測します。Objective-C では、次のプレフィックスのいずれかで統計するメソッド

  1. 割り当て、
  2. コピー、
  3. 可変コピー
  4. そして新しい

返されたオブジェクトの所有権を呼び出し元に譲渡していると見なされます。つまり、アプリケーションでメソッドを作成すると、自動解放されたオブジェクトを返すか、メソッド名から +1 保持オブジェクトを返すかを ARC が自動的に推測します。ただし、小さな注意点があります。次のように、「copy」で始まるメソッドがあるとします。

-(NSString*) copyRightString;

ARC は、返された文字列の所有権を呼び出し元に譲渡すると想定し、リリースを自動的に挿入します。呼び出されたメソッドと呼び出し元のメソッドの両方が ARC を使用してコンパイルされている場合、すべてがうまく機能します。

しかし、「copyRightString」メソッドが ARC でコンパイルされていないサード パーティのライブラリにある場合、返された文字列を過度に解放することになります。これは、呼び出し元のコードで、ARC コンパイラがリリースを挿入して、「コピー」メソッドによって増加した保持カウントのバランスを取るためです。

逆に、サード パーティのライブラリが ARC でコンパイルされていて、メソッドがそうでない場合、メモリ リークが発生します。

ここで 2 つの質問があります。メソッドの名前がcopyで始まるため、ARCが処理するオブジェクトを解放するメソッドを呼び出す責任があります。

2. サード パーティのライブラリが ARC でコンパイルされていて、メソッドがそうでない場合、メモリ リークが発生するのはなぜですか?メソッド名がコピーで始まるので、コードをリリースします。

私は明確であることを願っています!

4

1 に答える 1

3

この例では-copyRightString、特定の問題を示すためにメソッド名が選択されています。メソッドのシグネチャは、メソッドが著作権情報を含む文字列を返すことを示唆しているため、プログラマーは、メソッドが自動解放された値を返すことを期待します。しかし、誤ってメソッド名が で始まるcopyため、ARC はそれが保持された値を返すことを期待しています。メソッドの実装は次のようになります。

- (NSString *)copyRightString
{
   return [NSString stringWithFormat:@"Copyright %d %@", 
                                     self.copyRightYear,
                                     self.companyName];
}

このメソッドを ARC を使用せずにサード パーティのライブラリでコンパイルすると、メソッドは自動解放された値を返します。これを ARC コードから使用すると、ARC は名前が で始まることを認識し、copyこのメソッドが保持された (自動解放されない) 値を返すことを期待します。そのため、戻り値を 1 回頻繁に解放します。それがオーバーリリースの部分です。

一方、このメソッドを ARC でコンパイルすると、ARC は名前が で始まるcopyことを認識するため、メソッドが保持された値を返すことを確認します。ただし、非 ARC からこのメソッドを使用するプログラマは、メソッドが自動解放された値を返すことを期待する場合があります (メソッドのシグネチャが、著作権情報を含む文字列を返すことを示唆しているため)。そのため、コード内でオブジェクトを解放しないため、メモリ リークが発生します。

于 2012-06-19T14:01:08.040 に答える