LoginSignup
4
4

More than 5 years have passed since last update.

[NSMutableDictionary dictionary]でインスタンス生成した時にautoreleaseされる

Last updated at Posted at 2015-09-10

前提

tableViewを軽くするために、一回読み込んだ画像をキャッシュして再表示する時にNSMutableDictionaryでハマったのでメモ。

ハマったポイント

最初に画面表示したときはNSMutableDictionaryが読めたのにスクロールしてcellForRowAtIndexPath:が再度呼ばれたときにNSMutableDictionaryにアクセスしようとするとEXC_BAD_ACCESSとなってアプリが落ちる。

落ちたソース

- (void)viewDidLoad {
    [super viewDidLoad]
    dic = [NSMutableDictionary dictionary];
}

〜 中略 〜

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

〜 セルの再利用とかごにょごにょ 〜
  //再読み込みするとここで落ちる
    if([self.dic objectiveForKey:indexPath]){
        cell.imageView.image = [self.dic objectiveForKey:indexPath];
    }else{
        [self.dic setObject:image forKey:indexPath];
        cell.imageView.image = [self.dic objectiveForKey:indexPath];
    }
}

原因

落ちたときのログを見てみると
アクセスしようとしたインスタンスはすでにdeallocされてるよ!!
との表記。。。
人為的にreleaseしてないよ!!とおもいながらappleのリファレンスを見てみると。
NSDictionaryにdictionaryの表記が!!!
そこには
このメソッドは空の可変NSDictionaryを返すよ!
ただ一時的な利用以外はちゃんとalloc initしてね!
との表記。

後々話を聞いてみるとdictionaryでインスタンスを生成するとautorelease対象となってしまうらしい。
勉強不足でautoreleaseでreleaseされるタイミングはよくわかっていないが
ざっくりと誰もそのインスタンスを参照しなくなったら勝手にreleaseされるものだと思っている。

推測だが画面が最初に表示されるタイミングはviewDidLoadでインスタンスを生成してtableViewの初回表示までは参照されていたが
表示し終わったあと誰も参照してないから勝手にreleaseされたものだと思われる。

修正方法

appleのリファレンスどおり一時的利用以外の利用をしたいため
ちゃんとalloc initしてあげたら落ちなくなった。

dic = [[NSMutableDictionary alloc]init];

まだまだ勉強不足でつらい。。。
いっぱいソース書くぞー

追記(9/13)

プロジェクト自体がMRC環境でした。

記述していなかったですが

- (void) dealloc{
[dic release];

しています。

4
4
3

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
4
4