LoginSignup
3
3

More than 5 years have passed since last update.

Objective-Cのお勉強:リファレンスカウンタ

Last updated at Posted at 2015-01-21

Objective-Cを勉強中に出た疑問の自分用メモ。
メモリ管理に使っているリファレンスカウンタについて。
お勉強のため、ARCはオフ。

勉強資料は以下のサイト。
今さら聞けないObjective-Cのメモリ管理 弱い参照と強い参照って何? | Developers.IO

Car.m
#import "Car.h"

@implementation Car

/* setter を使う場合 */
- (void)setEngine:(Engine *)newEngine {
  [newEngine retain];
  [engine release];
  engine = newEngine;
}

/* property を使う場合
@synthesize engine;
*/

- (void)dealloc {
  NSLog(@"dealloc Car");  
  [engine release];
  [super dealloc];
}

@end

何がわからなかったかっていうと、setEngine:のあたり。

- (void)setEngine:(Engine *)newEngine {
  [newEngine retain];    // newEngineのリファレンスカウンタは2
  [engine release];    // engineのリファレンスカウンタは0
  engine = newEngine;    // engineのリファレンスカウンタは2 ←!?!?!?!?!?
}

なんで急にengineのリファレンスカウンタが2になんのよ!
retainしてないぞ!ってのが今回の疑問。

newEngineインスタンスをengineに代入した時点で、engineのリファレンスカウンタもnewEngineのものがコピー?されてしまっているってことかな?

[newEngine retain]をもう一つ挟んで、リファレンスカウンタを確認すると、newEngineもengineもカウンタは3になるので、多分合ってる気がする。

- (void)setEngine:(Engine *)newEngine {
  [newEngine retain];    // newEngineのリファレンスカウンタは2
  [newEngine retain];    // newEngineのリファレンスカウンタは3
  [engine release];    // engineのリファレンスカウンタは0
  engine = newEngine;    // engineのリファレンスカウンタは3、newEngineもリファレンスカウンタは3
}

ちなみにリファレンスカウンタを確認するには、retainCountを使う。
使用例はこんな感じ↓

printf("engine retainCount:%d\n", (int)[engine retainCount]);
engine retainCount:3

(追記)いただいたコメントを受けて、もう一回カウンタの挙動を確認してみました。

- (void)setEngine:(Engine *)newEngine {
  [newEngine retain];
  [engine release];
  engine = newEngine;

  printf("engine retainCount:%d\n", (int)[engine retainCount]);  // engineのカウンタは2
  printf("newEngine retainCount:%d\n", (int)[newEngine retainCount]);  // newEngineのカウンタは2

  [engine retain];
  printf("engine retainCount:%d\n", (int)[engine retainCount]);  // engineのカウンタは3
  printf("newEngine retainCount:%d\n", (int)[newEngine retainCount]);  // newEngineのカウンタは3

  [newEngine retain];
  printf("engine retainCount:%d\n", (int)[engine retainCount]);  // engineのカウンタは4
  printf("newEngine retainCount:%d\n", (int)[newEngine retainCount]);  // newEngineのカウンタは4

engineをretainしたりnewEngineをretainするたびにそれぞれのリファレンスカウンタを確認してみたら、おー、同じ値が出てきました。
engine=newEngine の代入式で、両変数が同じリファレンスカウンタ(正確には、同じオブジェクト)を参照していることがわかりました!
tomohisaotaさん、ありがとうございました!

3
3
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3