2011-01-11 5 views
0

この質問は少し混乱しました。 ".h"ファイルにあります。Objective cの保持とコピーについての質問

@property (nonatomic,retain) NSMutableString *str1; 
@property (nonatomic,copy) NSMutableString *str2; 

".m"ファイルにあります。

NSMutableString *testRetain = [[NSMutableString alloc] initWithString:@"prefix"]; 
NSLog(@"retain count is %d",[testRetain retainCount]); 
NSLog(@"mem add is %p",testRetain); 

str1 = testRetain; 
NSLog(@"retain count is %d",[testRetain retainCount]); 
NSLog(@"mem add is %p",testRetain); 

str2 = testRetain; 
NSLog(@"retain count is %d",[str2 retainCount]); 
NSLog(@"mem add is %p",str2); 

すべてのretainCountとメモリアドレスが同じです。 @property(nonatomic、retain)は、pointedオブジェクトのretainCountを追加します。したがって、コードの2番目の部分は、同じメモリアドレスと異なるcontainsCountをコードの最初の部分から出力する必要があります。 と@property(nonatomic、copy)はオブジェクトを新しい領域にコピーします.3番目のコード部分は、最初の部分から別のメモリアドレスを出力します。 なぜ私はこの結果を得たのですか? ありがとうございました。

+0

どのような結果が得られましたか? –

+3

'str1 = testRetain'はivarを直接同じメモリアドレスに設定しています。アクセサーを使用するには、 'self.str1 = testRetain;を使用する必要があります。 self.str2 = testRetain' – mackross

+0

マックロスが正しいです。 –

答えて

4

2点。まず、最も重要なのは、デバッグツールとしてretainCountを使用しないことです。期待している価値が得られない理由はたくさんあります。それはドキュメントに多くのことを述べています。

しかし、この場合、ポイント2の理由は、アクセサーを使用するのではなく、変数に直接アクセスしているからです。

の代わりに:

str = testRetain; 

試してみてください。

self.str = testRetain; 
3

"self.str1"の代わりに "str1"を使用すると、プロパティの(おそらく合成された)アクセサメソッドを経由しないため、メモリ管理が行われません。

さらに、-retainCountメソッドを使用することに非常に注意する必要があります。 Cocoa Touchはしばしば、保持カウント(内部保持、解放、オートレリース、定数オブジェクトの「特別な保持」カウントの保存など)で非常に奇妙なことを行い、効果的に使用することは難しくなります。

保持カウントを使用するのではなく、保持カウント(-copy、-alloc、-retain、+ new、-mutableCopy)を「オブジェクトの所有権を主張する」としてインクリメントし、 -releaseまたは-autorelease)を「オブジェクトの所有権を放棄」とします。したがって、使用している各オブジェクトを常に所有していて、それらを終了したらそれらを放棄する限り、リークとクラッシュの両方を避ける必要があります。

3

あなたが使用する必要があり、実際にこのようなコードです:

self.str1 = ...; 

この方法でのみsetterメソッドが呼び出されます。このようにコーディングすることで

str1 = ...; 

あなたが実際にそのため何の保持/コピーが起こっていない、setterメソッドを呼び出すことなく、直接インスタンス変数にアクセスしています。

1

str1 = testRetain;は、同じメモリアドレスに直接IVARを設定しています。 アクセサーを使用するには

self.str1 = testRetain; 
self.str2 = testRetain;