6

これが私がよく目にする一般的な習慣です(非常に人気のあるiPhone開発者の本からのものを含む)

.hファイル内:

@interface SomeViewController : UIViewController
{
  UIImageView *imgView;
}

.mファイルのどこか:

imgView = [[UIImageView alloc] initWithFrame:[[UIScreen mainScreen]
applicationFrame]];
[imgView setImage:[UIImage imageNamed:@"someimage.png"]];
[self addSubview:imgView];
[imgView release];

そして後で、私たちはこれを見ます...

- (void) dealloc
{
  [imgView release];
  [super dealloc];

} 

imgViewには一致する割り当てとリリースがあるので、deallocでのimgViewのリリースは必要ですか?

addSubview呼び出しによって保持されるimgViewはどこで説明されますか?

4

6 に答える 6

9

コードが正しくありません。割り当てが解除された後、リリースするimgViewことになります。

.mファイルでは、次のようになります。

  1. allocそれ->あなたはそれを所有しています
  2. サブビューとして追加->あなたとUIViewがそれを所有します
  3. releaseそれ->あなたはそれを所有していません

次に、では、上記の手順3で確立したようにdealloc、あなたはreleaseimgViewを所有していません。を呼び出す[super dealloc]と、ビューはすべてのサブビューを解放し、例外が発生すると思います。

のivarを保持したい場合は、サブビューとして追加した後で呼び出さないimgViewことをお勧めします。同じままにしてください。そうすれば、ある時点でビュー階層から削除された場合でも、それへの有効な参照があります。releasedeallocimgView

于 2009-05-05T02:13:38.977 に答える
0

init でのリリースが正しくありません。

あなたは「常識」と名前のない本について言及しました。Apple の標準的な例を見ることをお勧めします: ViewTransitions は、この場合の良い例です (そして起動する 2 つのビュー;)

http://developer.apple.com/iphone/library/samplecode/ViewTransitions/index.html

于 2009-05-05T02:39:09.510 に答える
0

基本的な答えは、[imgView release]サンプル コードには 1 つだけ存在する必要があるということです ( addSubview の後であろうと dealloc であろうと)。ただし、 から削除[imgView release]してからdealloc残しaddSubviewます。

iPhone には落とし穴があります。を使用するとdidReceiveMemoryWarning、オブジェクト (ビュー全体を含む) を下から解放することができます。アプリケーション全体の保持セットがあり、メモリを尊重しない場合、アプリケーションが単に強制終了されていることに気付く可能性があります。

良い例は次のとおりです:
ネストされた 3 つのビューのセットを考える場合、View 1-> View 2-> View 3. 次に、' viewDidLoad' と ' viewDidUnload' の呼び出しを考えます。ユーザーが現在「View 3」にいる場合、View1 がアンロードされている可能性があり、これが厄介なところです。
内部にオブジェクトを割り当て、viewDidLoadサブビューに追加した後に解放しなかった場合、view1 がアンロードされたときにオブジェクトは解放されませんが、view1 はまだアンロードされています。
viewDidLoadが再び実行され、コードが再び実行されますが、オブジェクトのインスタンス化が 1 つではなく 2 つになりました。1 つのオブジェクトは、以前にアンロードされたビューでノーウェアランドになり、新しいオブジェクトは現在表示されているビュー用になります。すすぎ、泡立て、繰り返すと、アプリケーションがメモリ リークによってクラッシュすることがわかります。

この例では、指定されたコード ブロックが揮発性であり、(メモリまたはアンロードされたビューが原因で) 再度実行される可能性がある場合、dealloc から削除[imgView release];し、addSubView の後に残します。

基本的な保持/解放の概念に関するリンクは次のとおりです: http://www.otierney.net/objective-c.html#retain

于 2009-05-05T12:39:59.893 に答える
0

(コメントを追加するのに十分な評判はまだありません。)

@bentford: 間違っている場合は訂正してください。ただし、imgView プロパティの合成セッターを使用するには、「self.imgView」を使用する必要があると思います。

self.imgView = [[UIImageView alloc] initWithFrame:[[UIScreen mainScreen]

自我がなければ。、ivarを使用しているだけで、追加の保持を取得していません。

于 2009-05-15T02:33:30.287 に答える
-1

はい、そのコードには問題があります。imgViewのリリースが早すぎるため、まれにクラッシュが発生する可能性があり、オブジェクトを保持せずにインスタンス変数に格納し、一般的にメモリ管理を間違った方法で行っています。

これを行う1つの正しい方法は次のとおりです。

@interface SomeViewController : UIViewController
{
    UIImageView *imgView;
}
@property (nonatomic, retain) UIImageView *imgView;

そして実装では;

@synthesize imgView;

モジュールのどこかに:

//Create a new image view object and store it in a local variable (retain count 1)
UIImageView *newImgView = [[UIImageView alloc] initWithFrame:self.view.bounds];
newImgView.image = [UIImage imageNamed:@"someimage.png"];

//Use our property to store our new image view as an instance variable,
//if an old value of imgView exists, it will be released by generated method,
//and our newImgView gets retained (retain count 2)
self.imgView = newImgView;

//Release local variable, since the new UIImageView is safely stored in the
//imgView instance variable. (retain count 1)
[newImgView release];

//Add the new imgView to main view, it's retain count will be incremented,
//and the UIImageView will remain in memory until it is released by both the
//main view and this controller. (retain count 2)
[self.view addSubview:self.imgView];

そして、dealloc は同じままです。

- (void) dealloc
{
    [imgView release];
    [super dealloc];
}
于 2009-05-14T03:20:29.387 に答える