29

UIWebView を使用するアプリのクラッシュが発生しています。通常、ページが完全に読み込まれておらず、UIWebView が stopLoading セレクターに送信された場合です。または、UIWebView がページを完全にロードしたとき。私は持っていEXC_BAD_ACCESSます。スタックは次のようになります。

#0  0x95bb7688 in objc_msgSend
#1  0x30a671db in -[UIWebView webView:decidePolicyForNavigationAction:request:frame:decisionListener:]
#2  0x3024a10d in __invoking___
#3  0x30249ff8 in -[NSInvocation invoke]
#4  0x358ab160 in HandleDelegateSource
#5  0x302452c1 in CFRunLoopRunSpecific
#6  0x30244628 in CFRunLoopRunInMode
#7  0x32044c31 in GSEventRunModal
#8  0x32044cf6 in GSEventRun
#9  0x309021ee in UIApplicationMain
#10 0x0000239c in main at main.m:13

私にとって最も奇妙なwebView:decidePolicyForNavigationAction:request:frame:decisionListener:のは、UIWebView ドキ​​ュメントにそのようなセレクターがないため、UIWebView に送信されるセレクターです。Cocoa (cocoa touch ではない) WebView 専用です。UIWebView またはそのデリゲートに問題があると思われます。しかし、ブレークポイントを設定してそれらを監視することはできません。この状況でより多くの情報を得る方法を教えてください。

4

6 に答える 6

87

ビューを離れる前に、webView の読み込みを停止し、デリゲートを削除する必要があります。

// ARC (correct solution)
- (void)dealloc {
    [_webView setDelegate:nil];
    [_webView stopLoading];
}

// non ARC
- (void)dealloc {
    [webView setDelegate:nil];
    [webView stopLoading];
    [webView release];
    [super dealloc];
}

// ARC (older solution)
- (void)viewWillUnload {
    [webView setDelegate:nil];
    [webView stopLoading];
}

Apple ドキュメントの説明: 重要 デリゲートを設定した UIWebView のインスタンスをリリースする前に、まずデリゲート プロパティを nil に設定する必要があります。これは、たとえば、dealloc メソッドで行うことができます。

于 2009-11-13T10:54:23.450 に答える
9

NSZombie をオンにして、リリースが早すぎるかどうかを確認してください。

ビューの読み込みをキャンセルし、すぐにビュー階層を破棄して、UIWebView がそれを台無しにする前に何かが解放されている可能性があります。

この場合、バックトレースは明らかにデリゲートが早期に解放されているように見えます。委任関係は一般的に弱く、GC がないため、このようなクラッシュの原因となるダングリング参照の素晴らしいソースとなります。

于 2009-08-31T20:51:28.407 に答える
2

スクロールしている UIWebView で EXC_BAD_ACCESS クラッシュが発生していましたが、これは iPad でのみであり、UIWebView を含むビュー コントローラーを閉じたときにユーザーが UIWebView のスクロールを終了した場合のみでした。

ここでデリゲートを nil に設定しても問題は解決しませんでしたが、別の問題で別の場所で解決策を見つけました。このコードを、閉じるボタンによって呼び出されるメソッドに追加しました。

for (id subview in webView.subviews){
        if ([[subview class] isSubclassOfClass: [UIScrollView class]]){
            [subview setContentOffset:CGPointZero animated:NO];
        }
    }

これにより、dealloc メソッドが呼び出される前にスクロールが停止します。これが問題のようです。

于 2012-03-27T16:30:21.157 に答える
1

私もこの正確なエラーを見ました。これは、保持されていない UIWebView に指定したデリゲート (私の場合は UIViewController) が原因でした。

于 2012-01-21T21:15:06.560 に答える
0

デリゲートを Web ビューから登録解除し、Web ビューの読み込みを停止する処理は、ViewController の dealloc メソッドから処理するのが最適です。

viewWillDisappear が失敗する可能性がある例として、ViewControllerが別の ViewController の子である場合、アニメーションを使用して親 ViewController のビューから ViewController のビューを削除することをトリガーできます。同時に、ViewController をその親から削除し、その参照を nil にすることができます。その時点で、ViewController は nil になり、viewWillDisappear が呼び出されることはありません。つまり、WebView デリゲートがクリーンアップされることはありません。

dealloc を使用して、WebView が常にクリーンアップされるようにします。

于 2013-08-19T11:52:48.010 に答える