5

次のコードを使用してサブイメージを描画します

UIImage* subIm = getSubImage( large, rect );
[subIm drawInRect:self.bounds];

ここで、getSubImageは次のように定義されます

    UIImage* getSubImage(UIImage* uim, CGRect rc){
      CGImageRef imref  = CGImageCreateWithImageInRect(uim.CGImage, rc); 
      UIImage*   sub = [UIImage imageWithCGImage:imref];
      CGImageRelease(imref);
        NSLog(@"subimage retainCount=%d", [sub  retainCount]); // is 1
      return sub;
   }//getSubImage

コードは正しいですか?

「CGImageRelease」imrefは安全ですか?

サブ「CGImageRetained」のimrefはありますか?

subImをリリースする必要がありますか(リリースするとエラーが発生します)?

subImはautorelease-poolに含まれていますか?含まれている場合、これをどのように知ることができますか?

一般に、オブジェクトが(デバッグ目的で)自動解放プールに含まれているかどうかを確認できますか?

4

4 に答える 4

15

-retainCount を呼び出さない

保持カウントによって返される数値は、オブジェクトの絶対保持カウントです。それらはフレームワークの実装の詳細であるため、制御できない多くの保持が行われている可能性があります。コードのメモリ管理を検証するより良い方法は常にあります。

保持カウントはデルタとしてのみ考慮されるべきです。保持カウントを増加させる場合は、減少させる必要があります。

与えられた:

UIImage* getSubImage(UIImage* uim, CGRect rc){
  CGImageRef imref  = CGImageCreateWithImageInRect(uim.CGImage, rc); 
  UIImage*   sub = [UIImage imageWithCGImage:imref];
  CGImageRelease(imref);
    NSLog(@"subimage retainCount=%d", [sub  retainCount]); // is 1
  return sub;
}//getSubImage

imageWithCGImage:自動解放されたオブジェクトを返します。imageWithCGImage:保持カウントは、保持カウントに影響を与える可能性のあるさまざまなこと (キャッシングなど) を内部的に実行している可能性があるため、無関係です。

get*は、Cocoa プログラミングで使用する奇妙なパターンです。あなたはそれほど多くは見ていません。

私は次のようなものを提案します:

- (UIImage *) subImage: (UIImage *) anImage inRect: (CGRect) aRect
{
      CGImageRef imageRef  = CGImageCreateWithImageInRect(anImage.CGImage, aRect); 
      UIImage*   subImage = [UIImage imageWithCGImage: imageRef];
      CGImageRelease(imageRef);
      return subImage;
}
于 2010-12-28T18:50:14.960 に答える
6

メモリ管理には命名規則があります。すべてのCocoa コードは次の規則に従います。

基本的なメモリ管理規則

このドキュメントを読み、ルールに従うことを強くお勧めします。命名規則も Cocoa の一部です。

リファレンス ドキュメントから:

作成したオブジェクトはすべてあなたが所有します。名前が「alloc」または「new」で始まるか、または「copy」を含むメソッド (たとえば、alloc、newObject、または mutableCopy) を使用して、オブジェクトを「作成」します。

所有しているオブジェクトを使い終わったら、それらの所有権を放棄する必要があります。release メッセージまたは autorelease メッセージを送信することにより、オブジェクトの所有権を放棄します (autorelease については、「Autorelease」で詳しく説明します)。したがって、Cocoa の用語では、オブジェクトの所有権を放棄することは、通常、オブジェクトを「解放する」と呼ばれます。

Core Foundation フレームワークの C 関数にも同様のルールがあります。ただし、そのような自動解放のようなものはありません。C 関数を使用して Objective-C オブジェクトを作成する場合は、ドキュメントのすべてを明確にする必要があります。

そして、これはあなたに役立つかもしれません: imageWithCGImageとメモリ

于 2010-12-28T16:43:34.810 に答える
4

SubIm は AutoRelease プールに登録されます。これは、このオブジェクトが実際にはクラス メソッド imageWithCGImage によって作成され、クラス メソッドによって作成されたインスタンスは常に自動解放されたインスタンスを返すという規則であるためです。

関数を定義するために Obj-C 構文ではなく C 構文を使用している理由がわかりませんが、コードは正しいです

于 2010-12-28T13:27:03.857 に答える
0
  CGImageRelease(imref);
    NSLog(@"subimage retainCount=%d", [sub  retainCount]); // is 1
  return sub;

メソッドには alloc、retain、copy... というキーワードがないため、返す前に UIImage を自動解放する必要があります。しかし、UIImage のファクトリ メソッドは既にそれを行っています。サブを自動解放しても、保持カウントは 1 のままであることに注意してください

于 2010-12-28T13:28:01.497 に答える