10

IBOutlets のメモリを管理する最適な方法を判断するために、Apple のドキュメントとサンプル コードを確認してきました。控えめに言っても、私は少し混乱しています。

CurrentAddress サンプル コードは、IBOutlets をプロパティとして宣言します。

@interface MapViewController : UIViewController <MKMapViewDelegate, MKReverseGeocoderDelegate>

{
    MKMapView *mapView;
    UIBarButtonItem *getAddressButton;
}
@property (nonatomic, retain) IBOutlet MKMapView *mapView;
@property (nonatomic, retain) IBOutlet UIBarButtonItem *getAddressButton;

偉大な。そして、これらは dealloc で解放されます:

- (void)dealloc
{
    [mapView release];
    [getAddressButton release];
    [super dealloc];
}

これらのプロパティを割り当てるように設定する必要はありませんか? 保持するように設定すると、IBOutlet の保持カウントが 2 回増加するためです。1 回目はペン先がロードされたとき、もう 1 回はプロパティが設定されたときです。そして、dealloc で解放する代わりに、これらのプロパティを nil に設定する方がよいのではないでしょうか?

4

5 に答える 5

7

Apple ドキュメントには、iOS のプロパティを保持する必要があると記載されています。
保持されたコンセントは、 とnilの両方で解放して 'ed にする必要がdeallocありviewDidUnloadます。

Mac では、スーパービューによって保持されないすべてのアウトレットは、nib をロードするときに自動的に保持されます。iOSの場合はそうではありません。そのため、ビュー階層内のビュー以外のアウトレットのみを保持することが理論的に有効です。

このトピックに関する非常に役立つ Jeff LaMarche の投稿があります: Outlets, Cocoa vs. Cocoa Touch

于 2011-03-08T13:29:32.677 に答える
2

nib ローダーがすべてのロードとすべての IBOutlets の接続を完了すると、ロードしたすべてのオブジェクトを自動解放します。IBOutlet プロパティが として宣言されている場合assign、それが指すオブジェクトは、次に自動解放プールが空になったときに削除されます。

プロパティを直接解放する代わりに、dealloc でプロパティを nil に設定できます。結果は同じです。注意すべきことは、セッターの独自の実装を提供した場合、オブジェクトの他のメンバーの一部が既に解放されている可能性があることに留意する必要があるということです。

于 2011-03-08T13:30:40.873 に答える
1

これは、MacOSX と iOS では異なります。iOS では、ビューがロードされて nib 接続が確立された後、保持カウントは 2 になります。

これらの各要素は、ビューによって 1 回、コントローラーによって 1 回保持されます。ビュー内の追加要素は、ビューのみによって保持されます。

コントローラーが 2 つの要素を解放すると、それらの保持カウントが 1 に減ります。その後、[super dealloc] が呼び出されます。UIViewController の dealloc に [view release] があるため、ビューは解放されます (他の場所に保持されていないか、以前に解放されていない限り)。ビューの割り当てが解除されると、そのサブ ビューが解放され、最終的に要素が完全に解放されます。

dealloc で [object release] が好まれる理由は、[self setObject:nil] を記述すると、キーと値のコーディング (または独自のコード) によって追加のコードが実行される可能性があるためです。これにより、コントローラー自体の割り当て解除中に、他のオブジェクトがコントローラーと対話する可能性があります。同じ理由で、セッターを init メソッドで使用しないでください。

リリースだけを行うもう 1 つの理由があります。値を nil に設定せずにそのままにしておくことで、後でコードが割り当て解除中にオブジェクトのその変数に誤ってアクセスしたかどうかに気付くでしょう。これにより、他の方法では追跡が困難なバグを見つけることができます。

于 2011-03-08T13:39:30.243 に答える
0

@synthesizeこれらのプロパティを想定しています。そうでない場合は、手動で解放する必要があります。プロパティが設定されているときに保持し続けると、メモリリークが発生するというあなたの仮定は非常に正しいです。

@synthesize考えてみましょう.... ファンシーステートメントが登場する前は、プロパティはどのようなものでしたか?

id _propertyName; // the ivar

- (id) propertyName {
  return _propertyName;
}

- (void) setPropertyName:(id)v {
  if (_propertyName) {
    [_propertyName release]; // release the previously retained property
  }
  _propertyName = [v retain]; // retain this one so it doesn't fly away on us
}

@synthesize はクールでそれを生成するので、これを入力する必要はありません。being@synchronizedとして何かを指定しなければ、ブロックも生成されますnonatomic。これも非常に優れています。

assignの代わりに指定すると、次のretainようになります

id _propertyName; // the ivar

- (id) propertyName {
  return _propertyName;
}

- (void) setPropertyName:(id)v {
  _propertyName = v;
}

これは、物がオブジェクトではない場合にできる唯一のことです。なぜなら、それらは値に過ぎないからです (値型とも呼ばれます。オブジェクトは参照型です)。値型は保持できないため、他の型のブロックは意味がありません。BOOL を使用して保持プロパティを作成し、LLVM または GCC が何をするように指示するかを確認してください ;)

于 2011-03-08T13:40:40.497 に答える
0

これらのプロパティを割り当てるように設定すべきではありませんか? 保持するように設定すると、IBOutlet の保持カウントが 2 回増加するためです。

まあ、あなたが投稿したコードはそのままです。

使用する場合:

@property (nonatomic, retain) IBOutlet MKMapView *mapView;

MKMapViewオブジェクトを作成し、呼び出すたびにそれを保持するセッターメソッドを作成するようにxCodeに指示しているだけです

yourMapViewController.mapView = someMapView; // from out

// or

self.mapView = someMapView; // from in

その後、mapView の保持カウントが +1 増加し、MapViewController コードでこれが必要になるため、mapView をポイントして管理できるようになりました...

IB nib ファイルについては心配しないでください...

UIViewController を nib でロードすると、クラス MapViewController : UIViewController の場合、MapViewController を解放すると IB nib オブジェクトが解放されます...保持する objectS に注意してください...

于 2011-03-08T13:41:13.663 に答える