3

By books はまず、次の例のように、「無効な」参照に関する問題を (ARC を使用して) 説明します。

NSDate* date1=[[NSDate alloc]init];
NSDate* date2=date1;
[date1 release];
NSLog(@"%@",date2); // bad access

したがって、保持/解放メカニズムを理解しました。この場合、命令は次のようになります。

date2=[date1 retain];

しかし、強い/弱い参照について話すとき、それは私には矛盾しているように聞こえます:

「デフォルトでは、参照は強いです。オブジェクトを強い参照に割り当てると、ARC はそのオブジェクトを保持したいと想定し、それを暗黙的に保持します」

これは前に述べたことと矛盾していませんか?
date2 はデフォルトで強力であるため、暗黙的に date1 を保持する必要があり、不正なアクセス例外は発生しません。
もちろん、私は何かを誤解しています。誰かが私にこれをよりよく説明できますか?

4

2 に答える 2

15

通常はストロングが必要なためデフォルトですが、コンパイラは ARC を使用してオブジェクトの寿命を分析し、適切なタイミングでメモリを解放します。例えば:

- (void)someMethod
{
  NSDate* date = [[NSDate alloc] init]; // date is __strong by default
  NSLog(@"The date: %@", date); // date still contains the object created above

  // Sometime before this point, the object date pointed to is released by the compiler
}

弱い参照は、1 つ以上の他の強い参照がある間だけオブジェクトを保持します。最後の強い参照が壊れるとすぐに、オブジェクトはコンパイラによって解放され、弱いオブジェクト参照 (変数) はnilランタイムによって変更されます。これにより、上記の例のように、ローカル スコープでは弱い変数がほとんど役に立たなくなります。例えば:

- (void)someMethod
{
  __weak NSDate* date = [[NSDate alloc] init]; // The date created is released before it's ever assigned to date 
                                               // because date is __weak and the newly created date has no 
                                               // other __strong references
  NSLog(@"The date: %@", date); // This always prints (null) since date is __weak
}

ローカル スコープで弱い変数と強い変数が一緒に動作する例を確認するには (これは有用性が非常に限られているだけであり、ここでは弱い変数参照を示すためだけに示されています)。

- (void)someMethod
{
  NSDate* date = [[NSDate alloc] init]; // date stays around because it's __strong
  __weak NSDate* weakDate = date;

  // Here, the dates will be the same, the second pointer (the object) will be the same
  // and will remain retained, and the first pointer (the object reference) will be different
  NSLog(@"Date(%p/%p): %@", &date, date, date);
  NSLog(@"Weak Date(%p/%p): %@", &weakDate, weakDate, weakDate);

  // This breaks the strong link to the created object and the compiler will now
  // free the memory. This will also make the runtime zero-out the weak variable
  date = nil;

  NSLog(@"Date: %@", date); // prints (null) as expected
  NSLog(@"Weak Date: %@", weakDate); // also prints (null) since it was weak and there were no more strong references to the original object
}
于 2012-04-19T22:12:07.813 に答える