3

ARC の下にない場合、次のコードの場合、

.h

@property (nonatomic, retain) NSString *s;

.m

NSString *m = [NSString stringWithString:@"Hellow, World"];
s = [m retain];

// later on
s = nil; <-- will this release the ref count on the string and hence get the string released?
4

5 に答える 5

7

このように (つまり、インスタンス変数に直接アクセスして) 使用すると、いいえ、そうはなりません。ただし、プロパティのアクセサ メソッド ([self setS:nil];またはself.s = nil;) を使用する場合は、そうです。

また、オブジェクトを解放することとそのメモリを解放することは、2 つのまったく別のことであることに注意してください。オブジェクトは、強い参照がなくなった場合にのみ割り当てが解除されます。つまり、オブジェクトへの最後の参照があり、それを解放します。解放しても (以前に保持されていたために) 他の参照がある場合、まだ割り当ては解除されず、参照カウントだけが 1 つ減ります。

さらに、あなたの例のような保持されたプロパティがある場合は、1.基になるインスタンス変数に直接アクセスしてはいけません。2.次のようなことをしてください

NSString *m = [NSString stringWithString:@"Hellow, World"];
s = [m retain];

なんで?最初の行は単に不要だからです - 本当に、なぜ- [NSString stringWithString:]ですか? 定数文字列を作成してから、その正確なコピーを作成します-それは余分です。Cocoa の設計者が初心者だった場合、この行もメモリを浪費することになります。同じ不変文字列の 2 つの正確なコピーです。幸いなことに、NSString を実装した人は誰でもこの状況に備えており、このメソッドで引数が定数であることを確認し、定数である場合は何もせずに返すようにしました。したがって、同じポインターが返されますが、いくつかの追加objc_msgSendの呼び出しが行われます。これは問題ではありません。あなたがしたい。

2 行目も間違っています。繰り返しますが、バッキング ivar をそのまま使用しません。また、プロパティが宣言さretainれているのには理由があります。オブジェクトをプロパティに設定すると、そのオブジェクトは setter メソッドによって保持されます。手動で保持する必要はありません。

全体として、あなたが書いたほうがいいです

self.s = @"Hello World";

// ...

self.s = nil;

代わりは。

于 2012-08-21T06:50:12.560 に答える
2

この操作を行う正しい方法は次のようになります。

self.s = [NSString stringWithString:@"Hellow, World"]; // this will ensure that string is retained 

// later on
self.s = nil; // this will ensure that retain count is reduced. 

NSStringの割り当て解除は、iOS AutoreleasePoolに依存します。保持カウントを解放するため、次にGCを実行すると、その文字列の合計保持カウントがチェックされ、他の場所で使用されていない場合は、そのオブジェクトが削除されます。

于 2012-08-21T06:52:32.747 に答える
1

すべてのretain呼び出しは、一致する とペアにする必要がありますrelease。に割り当てることでnil、保持されているオブジェクトを放棄しています。

于 2012-08-21T06:50:21.547 に答える
1

objがプロパティの場合、

self.obj = nil;

実際にあなたのためにそれを解放します。

ただし、プロパティ、メンバー、またはローカル変数でない場合

 obj = nil;

その後、リリースのために管理する必要があります

于 2012-08-21T06:50:39.040 に答える
1

この場合、はい、プロパティを使用し、インスタンス変数を直接変更しないと仮定します。プロパティがARCstrongの代わりにあった場合retainも同様です。基本的に、合成されたプロパティは次のようになります。

- (void)setPropertyName:(NSString *)value {
  [value retain];
  [_propertyName release];
  _propertyName = value;
}

そのため、新しい値を割り当てると、新しい値が保持され、古い値が解放されます。新しい値と古い値が同じ場合、ほとんど影響はありません。

注:コード例では、オブジェクトを割り当てた後もオブジェクトを保持しているため、Cocoa メモリ管理ポリシーに従ってオブジェクトの所有権を取得していることに注意してください。そのため、プロパティを設定したら、リークを回避するためにオブジェクトreleaseまたはオブジェクトのいずれかを実行する必要があります (プロパティを使用すると、オブジェクトも保持されるため)。autorelease

于 2012-08-21T06:51:23.720 に答える