24

いくつかの情報源 (stackoverflow.com、cocoa-dev、ドキュメント、ブログなど) から、init メソッドと dealloc メソッドでアクセサーと設定 (foo、setFoo:) を使用するのは「間違っている」と聞いています。そうすることで、プロパティを監視している他のオブジェクトを混乱させる可能性がわずかにあることを理解しています。(簡単な例をここに示します)

ただし、次の理由により、この慣行には同意しないと言わざるを得ません。

新しい Objective-C ランタイム (iPhone のランタイムと 10.5 の 64 ビット ランタイム) では、対応する ivar を宣言せずにプロパティを宣言できます。たとえば、次のクラスは 10.5 または iPhone (シミュレータではなくデバイス) で問題なくコンパイルされます。

@interface Foo : NSObject { }

  @property (retain) id someObject;

@end

@implementation Foo

  @synthesize someObject;

@end

上記が完全に有効な Objective-C クラスであることを理解した上で、イニシャライザとメモリ管理の目的で dealloc メソッドを作成するとします (iPhone では GC を使用できないため)。イニシャライザと解放についてこれまでに読んだことはすべて、次の 2 つのメソッドを作成することにつながります。

- (id) init {
  if (self = [super init]) {
    //initialize the value of someObject to nil
    [self setSomeObject:nil];
  }
  return self;
}

- (void) dealloc {
  //setting someObject to nil will release the previous value
  [self setSomeObject:nil];
  [super dealloc];
}

ただし、ドキュメントと一般的な意見によると、これは「間違っています」。だから私の質問はこれです:

  1. アクセサーを使用せずに someObject を初期化するにはどうすればよいですか? コンパイラ (またはランタイムなど) が someObject が既に nil に設定されていることを保証すると言うかもしれませんが、それに依存するのは不適切な動作だと思います。C のバックグラウンドがかなりあるので、変数を適切に初期化していないためにかなりの数のバグを見てきましたが、これはほとんど変わらないようです。
  2. dealloc メソッドでアクセサーを使用することになっていない場合、someObject を解放するにはどうすればよいですか?

これらのいずれかに対する答えが「できない」である場合、init および dealloc メソッドでアクセサーを使用することがどうして悪いのでしょうか?

4

2 に答える 2

9

編集 (2013 年 2 月 13 日):以下のコメントで述べたように、特に ARC の追加以来、私はこれについて考えを変えました。ARC を導入する前は、 での ivar の割り当てが正しくないために、クラッシュを引き起こすバグがたくさん見られましたinit。IMO は、特にジュニア チームと協力して、アクセサーを使用する際のまれな問題initよりも、ivar アクセスの一般的なバグの方が重要でした。ARC はこれらの種類のバグを排除したので、 でアクセサを使用することで発生する可能性のある稀ではあるが発生する可能性のあるバグはinitより重要です。可能な他の場所のアクセサー (明らかに、アクセサー自体の内部でアクセサーを使用することはできません....)initdealloc


PRE-ARC の回答

のアクセサに反対する人たちには強く反対します-init。ほとんどすべての場合、これはアクセサーを使用するのに非常に適した場所であり、-init.

-deallocより厳しい要求です。私はそこでアクセサーを使用する自然な傾向があります (そのため、アクセサーはどこでも使用されます) が、KVO (またはセッターに変更通知を投稿する場合は NSNotifications) が原因で頭痛の種になる可能性があります。とは言っても、私は でアクセサーを使用していませんが-dealloc、非常に議論の余地があると考えており、Apple はそれについて非常に一貫性がありません (たとえばsetView:、UIViewController で呼び出していることはわかってい-deallocます)。

いずれにせよ、アクセサーの過小使用は、過剰使用の 100 倍のバグを引き起こしたと言えます。使用しない強い理由がある場合を除いて、私は常にそれらを使用する方向に誤ります.

于 2009-08-17T05:03:04.500 に答える
8

合成された ivar に直接アクセスできない現在の 10.5 の動作は、Apple によってバグと見なされていることを理解しています。直接アクセスできるはずですが、できません。

したがって、次のことができるはずです。

someObject = nil;

それ以外の

self.someObject = nil;

当面は、アクセサを直接使用することが、明示的な ivar を提供せずにこれを行う唯一の方法です。

更新: このバグは修正されました。あなたは今うまくやることができますsomeObject = nil

于 2009-08-16T04:13:31.740 に答える