強い参照と弱い参照を理解するために、以下の例を考えてみましょう。displayLocalVariableという名前のメソッドがあるとします。
-(void)displayLocalVariable
{
NSString myName = @"ABC";
NSLog(@"My name is = %@", myName);
}
上記のメソッドでは、myName変数のスコープはdisplayLocalVariableメソッドに制限されています。メソッドが完了すると、文字列「ABC」を保持しているmyName変数がメモリから割り当て解除されます。
次に、ビューコントローラのライフサイクル全体でmyName変数の値を保持したい場合はどうでしょう。このために、self.username = myName;
以下のように、変数myName(以下のコードを参照)への強い参照を持つユーザー名という名前のプロパティを作成できます。
@interface LoginViewController ()
@property(nonatomic,strong) NSString* username;
@property(nonatomic,weak) NSString* dummyName;
- (void)displayLocalVariable;
@end
@implementation LoginViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
-(void)viewWillAppear:(BOOL)animated
{
[self displayLocalVariable];
}
- (void)displayLocalVariable
{
NSString myName = @"ABC";
NSLog(@"My name is = %@", myName);
self.username = myName;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
@end
上記のコードでは、myNameがself.usernameに割り当てられ、self.usernameがmyNameへの強い参照(@propertyを使用して宣言したとおり)を持っていることがわかります(間接的に、「ABC」文字列への強い参照を持っています)。したがって、self.usernameが有効になるまで、文字列myNameはメモリから割り当て解除されません。
ここで、myNameをダミー参照であるself.dummyName = myNameに割り当てることを検討してください。ストロングリファレンスとは異なり、ウィークはmyNameへのストロングリファレンスが存在するまでのみmyNameを保持します。弱参照を理解するには、以下のコードを参照してください。
-(void)displayLocalVariable
{
NSString myName = @"ABC";
NSLog(@"My name is = %@", myName);
self.dummyName = myName;
}
上記のコードには、myNameへの弱い参照があります(つまり、self.dummyNameはmyNameへの弱い参照を持っています)が、myNameへの強い参照はないため、self.dummyNameはmyName値を保持できません。
ここで、以下のコードをもう一度考えます。
-(void)displayLocalVariable
{
NSString myName = @"ABC";
NSLog(@"My name is = %@", myName);
self.username = myName;
self.dummyName = myName;
}
上記のコードでは、self.usernameにmyNameへの強い参照があるため、myNameに強い参照が関連付けられているため、メソッドが終了した後でもself.dummyNameの値はmyNameになります。
これで、変数への強い参照を作成するたびに、保持カウントが1つ増え、変数は割り当て解除されずに保持カウントが0に到達します。
お役に立てれば。
strong
、weak
とunsafe_unretained
。