5

someObject = someOtherObject;設定とself.someObject = someOtherObject;someObject が @property (非アトミック、保持) SomeType someObject; で作成されたクラス プロパティである場合の違いを誰でも説明できますか?

明確にするために、次のようなものがあります。

@interface SomeClass : NSObject {
   SomeType* someObject;
}

@property (nonatomic, retain) SomeType* someObject;

@end

self なしでプロパティを使用すると、時々 EXC_BAD ACCESS が発生することに気付きました。これはかなりランダムに見えます。self を使用すると、プログラムは本来あるべき動作をします。self をスキップしてもコンパイラ エラーや警告は表示されないので、何らかの形で有効な構文だと思いますか?

4

4 に答える 4

5

self.someObject = someOtherObjectプロパティを利用します。プロパティは、セッターとゲッターを生成します。あなたのケースではretain、プロパティに属性を与えました。つまり、このプロパティを介して設定されたオブジェクトはretain、保持カウントを 1 増やすメッセージを自動的に受信します。さらに、メンバー変数の古い値は、その値releaseを減らすメッセージを送信されます。カウントを保持します。

保持カウントが 0 に達すると、オブジェクトの割り当てが解除されます。割り当て解除されたオブジェクトにアクセスしようとすると (たとえば、頻繁に解放しようとすると)、EXC_BAD_ACCESS ecxeption が発生します。

あなたの場合:

SomeOtherObject *soo = [[SomeOtherObject alloc] init]; //retain count: 1
self.someObject = soo; //soo's retain count is now 2
[soo release]; //soo's retain count is 1 again, as self still uses it.
[self doSomethingWithSoo];

ただし、セッターを使用しない場合は、リリースしてはいけませんsoo

SomeOtherObject *soo = [[SomeOtherObject alloc] init]; //retain count: 1
someObject = soo; //soo's retain count is still  1
[soo release]; //soo's retain count is 0, it will be deallocated
[self doSomethingWithSoo]; //will fail with an EXC_BAD_ACCESS exception, as soo does not exist anymore.
于 2011-02-03T09:26:41.017 に答える
2

プロパティは、データにアクセスするための便利な方法です。したがって、プロパティ @property (nonatomic、retain) SomeType* someObject; を宣言するとき。これは、アクセス中に合成された 2 つのメソッドがあることを意味します。

ゲッター:

-(SomeType*) someObject {
   return someObject;
}

セッター

-(void) setSomeObject:(SomeType*) obj {
   [someObject release];
   someObject = [obj retain];
}

したがって、プロパティと ivar の主な違いは、プロパティがセッター/ゲッター メソッドを動的に作成することです (そして、それらをオーバーライドできます)。しかし、someObject = new_val と書いているときは、メモリの場所への参照をコピーしているだけです。1 つのアセンブリ命令を除いて、追加の作業は行われません。

言及すべきもう 1 つのことがあります: アトミックと非アトミックです。アトミックでは、合成されたセッター/ゲッターは、他のスレッドでのセッターのアクティビティに関係なく、常に値全体がゲッターから返されるか、セッターによって設定されることを保証します。つまり、スレッド B がセッターを呼び出しているときにスレッド A がゲッターの途中にある場合、実際に実行可能な値 (おそらく自動解放されたオブジェクト) が A の呼び出し元に返されます。

非アトミックでは、そのような保証はありません。したがって、非アトミックはアトミックよりもかなり高速です。

編集:したがって、別のスレッドからアクセスされる変数がある場合、または/および追加の作業を行う必要がある場合(たとえば、保持、いくつかのフラグを上げる...)、選択はプロパティです。ただし、変数が頻繁にアクセスされる場合があり、プロパティを介したアクセスは大きなオーバーヘッドにつながる可能性があります。これは、プロセッサが合成してメソッドを呼び出すためにより多くの操作を実行する必要があるためです。

于 2011-02-03T09:22:47.613 に答える
1

それはすべてメモリ管理に関するものです。

あなたのクラス プロパティは、あなたの .h / .m ファイルにsomeObject注釈@property/を持つアクセサーを生成しました。@synthsize

でプロパティにアクセスする場合はsomeObject、プロパティに直接アクセスします。アクセスしているときは、メモリ管理を行うself.someObjectアクセサーを呼び出しています。[self someObject]

そのため、クラス プロパティを割り当てる必要がself.someObject = someOtherObject;ある場合は、setter を使用し、解放と保持を気にする必要がないため、より簡単に行うことができます。あなたのセッターが生成されたとき、それはあなたの@property (nonatomic, retain)ために保持を世話します。

于 2011-02-03T09:27:46.490 に答える
0

両者の違いは次のとおりです。

1) 「self」を使用しない場合。結果をメンバー変数に直接割り当てています。

2) 「自己」を使用している場合。そのプロパティでセッターメソッドを呼び出しています。[self setMyObject:...]; と同じです。

したがって、self.myobject の場合はその保持を保持し、それ以外の場合 (self なし)、alloc を使用していない場合は、自動解放されたオブジェクトとして扱われます。

ほとんどの場合、オブジェクトの初期化中を除いて、「self.」を使用したいと思うでしょう。

ちなみに、self.someObject = [someOtherObject retain]リテイクカウンターを増やすためにも使えます

于 2011-02-03T09:27:03.747 に答える