プロパティ

@interface MyObj : NSObject{
  NSMutableDictionary *dic;
}
@property (nonatomin,retain) NSMutableDictionary *dic;
@end

@implementation

-(id)initWithDic:(NSMutableDictionary *)param
{
  if(self = [super init]){
    dic = param;
  }
  return self;
}

-(void)dealloc
{
 [dic release];
 [super dealloc];
}

-(id)param:(NSString *)key
{
  return [dic objectForKey:key];
}
-(void)setParam:(NSString *)key value:(id)val
{
  [dic setObject:val forKey:key];
}

@end

上記の定義にはミスがある。


retainCountを確認する為のテスト関数を作ってみる。

-(void)retainCountCheck
{

  NSMutableDictionary *dictinary = [NSMutableDictionary dictionary]; // retainCount:1 autorelease付き
  MyObj *obj1 = [[MyObj1 alloc] initWithDic:dictionary]; // retainCount:2 になるべき
  MyObj *obj2 = [[MyObj1 alloc] initWithDic:dictionary]; // retainCount:3 になるべき
  MyObj *obj3 = [[MyObj1 alloc] initWithDic:dictionary]; // retainCount:4 になるべき
  MyObj *obj4 = [[MyObj1 alloc] initWithDic:dictionary]; // retainCount:5 になるべき
  NSLog(@"retain count: %d",[dictionary retainCount]); // 結果 retain count: 5 が出力されるべき
 
  // 関数内で作成したオブジェクトの解放(autoreleaseされていないもの)は省略
}

結果はretain count: 1である。
MyObjのプロパティ宣言でretainを指定してあるdicに代入されるNSMutableDictionaryのインスタンスはretainされていない。
このままでは、外部でreleaseされてしまった場合には、EXEC_BAD_ACCESSが発生してしまう。
なぜか。


以下のようにするとうまくいく。

-(id)initWithDic:(NSMutableDictionary *)param
{
  if(self = [super init]){
    self.dic = param;
  }
  return self;
}


つまり、自分自信のプロパティへの変数代入時にも、
「self.」を付けるべきということ。プロパティ宣言による、getter,setterが使用される為にはこうしなければならなかった。