ios WebView を TableCellで表示した際にメモリーリークした時の対処
ついにきた。
iosアプリを開発していたら、
実機テスト中に動作が重くなり、アプリがクラッシュした。
クラッシュしたのは前回実装したテーブル更新機能と、
追加で実装しようとしていたテーブルのデータ追加機能をさわっていた時。
ios UIRefreshControlでテーブルを引っ張ってからの更新 - 恥知らずのウェブエンジニア
xcodeのdebug menuのmemoryをみていくと
データ更新・追加を行うともりもりメモリを食っていく・・・
しばらく放っておいても全然開放されない・・・
まず調べた順番について、
- これは世に言う循環参照か?!
⇒試しにすべてweakに設定したみたが変化なし。っていうか
strong,weakの使い分けがしっくりきてないがこれはまた別の時に。
- セルが使い回せていない?!
⇒セルを使い回していると思いきやできていない??
下記のようにNSLogmを入れてみる。
結果大丈夫そう・・・
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSString *cellIdentifier = @"tableCell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if (cell == nil) { NSLog(@"NO REUSE CELL!!"); cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } return cell; }
- もんもんとした。
- 下のページに行き当たる
objective c - How to remove a subview from a cell's content view? - Stack Overflow
⇒どうやらtable cellの中に入れていた、webViewに問題があるっぽい。
確かにそう言われるとcellは使い回しているが、
中のwebViewがそのままならデータの更新・追加の際にもりもりメモリ食うのも納得できる。
下記のようにtagを指定してwebViewを入れる。
そして入れる前に該当のtagがあったら削除するようにしてみた。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSString *cellIdentifier = @"tableCell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if (cell == nil) { NSLog(@"NO REUSE CELL!!"); cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } NSString *hogeURL = [NSURL URLWithString:@"hoge.moe"]; CGRect frame = cell.contentView.bounds; frame = CGRectInset(frame, 5, 5); //対象tagで削除 [[cell.contentView viewWithTag:10] removeFromSuperview]; UIWebView *webView = [[UIWebView alloc] initWithFrame:frame]; NSString *hogeHTML = [self createMovieHTML:hogeURL frame:frame]; [webView loadHTMLString:movieHTML baseURL:nil]; webView.delegate = self; //tagをつける webView.tag = 10; [cell.contentView addSubview:webView]; webView = nil; return cell; }
これで改善されました!
更新・追加してもメモリが増加し続けることはなくなりました。
とは言え今後、cellの中に画像やテキストなどを入れた時も
いちいちtag付けて消さなきゃいけない・・・?
そんなことはないと思うが、それはその時試してみよう。
感謝致します。