プロパティ
@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が使用される為にはこうしなければならなかった。