UIWebView がクラッシュするのを防ぐ方法−2

このエントリーをはてなブックマークに追加
はてなブックマーク - UIWebView がクラッシュするのを防ぐ方法−2

追記:2012/5/11 どうもこれでもクラッシュすることがあるようです。真の原因が分かったら、どなたか、教えてください…
さらに追記しました:5/12 UIWebView がクラッシュするのを防ぐ方法-3 | Zero4Racer PRO Developer’s Blog

iOS5 で UIWebView を使用しているときはご注意-予期せぬクラッシュを防ぐ方法 | Zero4Racer PRO Developer’s Blog で基本的にとる方法として、delegateのリセット、removeFromSuperview、stopLoadingなどを上げたのですが、それでもうまくいきませんでした。理想的な方法ではないのですが、とりあえず落ちない(多分)ように修正したので報告しておきます。

WebViewの表示
WebViewの表示


落ちる典型のクラッシュログはこんな感じ

Incident Identifier: 4D932A22-85F0-4ED7-AAD5-8B9D77207992
CrashReporter Key: 92d191278ae2cc8971ec7375ba2d01242246f856
Hardware Model: iPad3,3
Process: TwitOverview [11240]
Path: /var/mobile/Applications/255B8BDB-8B16-4171-84D5-9F7DEC081A43/TwitOverview.app/TwitOverview
Identifier: TwitOverview
Version: ??? (???)
Code Type: ARM (Native)
Parent Process: launchd [1]

Date/Time: 2012-05-03 15:30:35.606 -0700
OS Version: iPhone OS 5.1 (9B176)
Report Version: 104

Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x00000000
Crashed Thread: 3


Thread 3 name: WebThread
Thread 3 Crashed:
0 libicucore.A.dylib 0x346f868c 0x34689000 + 456332
1 libicucore.A.dylib 0x34690f8c utext_setNativeIndex + 84
2 libicucore.A.dylib 0x34690f2e icu::RuleBasedBreakIterator::first() + 30
3 libicucore.A.dylib 0x34690e7c icu::RuleBasedBreakIterator::setText(UText*, UErrorCode&) + 116
4 libicucore.A.dylib 0x34690df8 ubrk_setText + 72
5 WebCore 0x332d4de4 WebCore::characterBreakIterator(unsigned short const*, int) + 84
6 WebKit 0x3248974a -[NSString(WebStringDrawing) __web_drawInRect:withFont:ellipsis:alignment:letterSpacing:lineSpacing:includeEmoji:truncationRect:measureOnly:renderedStringOut:drawUnderline:] + 1182
7 WebKit 0x32402078 -[NSString(WebStringDrawing) __web_drawInRect:withFont:ellipsis:alignment:letterSpacing:lineSpacing:includeEmoji:truncationRect:measureOnly:renderedStringOut:] + 108
8 WebKit 0x32401ffc -[NSString(WebStringDrawing) __web_drawInRect:withFont:ellipsis:alignment:letterSpacing:lineSpacing:includeEmoji:truncationRect:measureOnly:] + 100
9 WebKit 0x32401f88 -[NSString(WebStringDrawing) _web_drawInRect:withFont:ellipsis:alignment:lineSpacing:includeEmoji:truncationRect:measureOnly:] + 100
10 WebKit 0x32401f14 -[NSString(WebStringDrawing) _web_sizeInRect:withFont:ellipsis:lineSpacing:] + 80
11 UIKit 0x325cc804 -[NSString(UIStringDrawing) sizeWithFont:constrainedToSize:lineBreakMode:lineSpacing:] + 108
12 UIKit 0x32740f92 -[NSString(UIStringDrawing) sizeWithFont:constrainedToSize:lineBreakMode:] + 46
13 TwitOverview 0x000fe590 +[TOVTweetView calcApproxHeightWithWidth:tweetData:] (TOVTweetView.m:74)
14 TwitOverview 0x000fecb4 -[TOVTweetView layoutSubviews] (TOVTweetView.m:115)
15 UIKit 0x325a80d8 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 176
16 CoreFoundation 0x3197a1f4 -[NSObject performSelector:withObject:] + 36
17 QuartzCore 0x309f1a9e -[CALayer layoutSublayers] + 210
18 QuartzCore 0x309f16b6 CA::Layer::layout_if_needed(CA::Transaction*) + 210
19 QuartzCore 0x309f583c CA::Context::commit_transaction(CA::Transaction*) + 220
20 QuartzCore 0x309f5578 CA::Transaction::commit() + 308
21 QuartzCore 0x309ed4b2 CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 50
22 CoreFoundation 0x319efb14 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 12
23 CoreFoundation 0x319edd50 __CFRunLoopDoObservers + 252
24 CoreFoundation 0x319ee0aa __CFRunLoopRun + 754
25 CoreFoundation 0x3197149e CFRunLoopRunSpecific + 294
26 CoreFoundation 0x31971366 CFRunLoopRunInMode + 98
27 WebCore 0x332850f0 _ZL12RunWebThreadPv + 396
28 libsystem_c.dylib 0x3114072e _pthread_start + 314
29 libsystem_c.dylib 0x311405e8 thread_start + 0

落ちたスレッドだけ強調表示していますが、どうも表示を終わらせて、ビューが消えているのにもかかわらず、表示しようとしているために起きているよう。理論的には

webView.delegate=nil;
[webView stopLoading];
[webView removeFromSuperview];

で良さそうなのですが、それではうまくいきませんでした。それでとった方法は、
WebViewを持っているviewControllerを再利用し、複数回使用する時に毎回生成しない
という方法です。

通常は、StoryBoardで、segueを使っていたため、ViewControllerは、Segueで自動作成、自動解放されていたのですが、これを、古典的な、
[self presentModalViewController:detail animated:NO];

に変更して、UIStoryboardから、viewControllerを生成

if (!detail) {
UIStoryboard *story=[UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
detail = [story instantiateViewControllerWithIdentifier:@"TOVTweetDetailViewController"];
}
 [self presentModalViewController:detail animated:NO];

これで、detailは、いつ度作成されたものが使い回されます。再利用するために,描画の初期化関係を少し調整。
これで、今のところUIWebView周りで落ちない様になっているみたいです。

StoryBoardについては、来月発売iOS5プログラミングブックで、詳しく解説されています!この部分は、藤川さん Hiroyuki-Fujikawa.HD (cqa02303) on Twitter 担当!凄くいいです。

クラッシュ対策、うまくいくといいですが。。。

Comments

comments

Powered by Facebook Comments

2件のコメント
  1. […] iOS5 で UIWebView を使用しているときはご注意-予期せぬクラッシュを防ぐ方法 Tweet追記:2012/5/11 こちらの記事に更なる対策を書きました。この記事の内容だけで十分ではないみたいでした。UIWebView がクラッシュするのを防ぐ方法−2 | Zero4Racer PRO Developer’s Blog iPad向け、Twitter 俯瞰(一望)アプリ、TweetOverviewの開発も終盤に迫ってきました。現在、クラッシュの原因などをつぶしているところです。スクリーンショットはこちら。 詳細画面 こちらが詳細です。 一覧画面 一覧から、クリックすると、詳細が表示され、リンクが有れば詳細が表示されます。 Webviewを表示 ここでWebViewを使用しているのですが、ときどき落ちる現象が発生していました。 クラッシュで落ちるのですが、クラッシュレポートは以下のような感じでした。 Incident Identifier: 1EF46E57-4785-4434-A1DE-0E640AB9E6ED CrashReporter Key: 92d191278ae2cc8971ec7375ba2d01242246f856 Hardware Model: iPad3,3 Process: TwitOverview [13214] Path: /var/mobile/Applications/9BA9102E-ACB3-4573-B319-EEE6E3A080AA/TwitOverview.app/TwitOverview Identifier: TwitOverview Version: ??? (???) Code Type: ARM (Native) Parent Process: launchd [1] […]

  2. […] UIWebView がクラッシュするのを防ぐ方法−2 […]

UIWebView がクラッシュするのを防ぐ方法-3 | Zero4Racer PRO Developer's Blog にコメントする コメントをキャンセル

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください