UIWebView EXC_BAD访问

时间:2011-09-08 18:34:47

标签: iphone objective-c webview exc-bad-access dealloc

HY

我有一个UIView。在一种方法中,我分配一个WebView,并将其设置为retain属性。

    self->webView= [[UIWebView alloc] initWithFrame:self.frame];

然后我开始加载HTML字符串。加载后,我调整视图大小并启动​​一个callBack到superview来调整大小。它正在发挥作用。 我的问题是,如果用户在加载视图之前返回,则会释放视图。然后我的WebView抛出一个BAD_ACCESS。 这是dealloc方法:

-(void)dealloc{
[self.webView setDelegate:nil];
[self.webView stopLoading];  
[self setWebView:nil];
[htmlStr release];
[super dealloc];}

屏幕截图中显示了回调跟踪。有趣的是,如果我不发布WebView,它的工作就像魅力一样。如果我发布了WebView,那么当它被解除分配时,我会在日志中收到一条错误消息:

 ![bool _WebTryThreadLock(bool), 0x4e05150: Tried to obtain the web lock from a thread other than the main thread or the web thread. This may be a result of calling to UIKit from a secondary thread. Crashing now...][1]
编辑:已修复。事实证明,我的图像加载方法是有罪的。我开始一个新线程(NSOperationQueue和NSInvocationOperation)加载图像,并在完成后创建performSelectorOnMainThred: Whit,我在每个页面切换上加载了超过一百个小(1-2 KB)图像,这是一个非常大的开销。当我编写一个逐个下载一个线程中的图像的方法时,这个bug再也没有了

3 个答案:

答案 0 :(得分:1)

您正在从主要的其他步骤修改UI。这是禁止的,因为UIKit不是线程安全的(因此崩溃......)。如果要从其他线程修改UI,则必须使用:

performSelectorOnMainThread:withObject:waitUntilDone:

我在您的代码中注意到的另一件事是您错误地在-dealloc中发布了您的属性。你不应该使用这样的合成setter:

[self setWebView:nil];  // same as self.webView = nil;

你不应该,因为如果你开始在你的属性上使用KVO(键值观察),它会给你带来很多问题......而只是写:

[webView release];

或者,如果您想避免"The Heisenbug"

[webView release], webView = nil;

编辑:您也可以从这个问题的答案中受益:How to safely shut down a loading UIWebView in viewWillDisappear?

答案 1 :(得分:0)

请勿在dealloc中使用self.webView进行调用,只需使用webView

- (void)dealloc {
    if ([webView isLoading])
        [webView stopLoading];
    [webView setDelegate:nil];
    [webView release], webView = nil;
    [super dealloc];
}

答案 2 :(得分:0)

它已被修复。事实证明,我的图像加载方法是有罪的。我开始一个新线程(NSOperationQueue和NSInvocationOperation)加载图像,并在完成后创建performSelectorOnMainThred: Whit,我在每个页面切换上加载了超过一百个小(1-2 KB)图像,这是一个非常大的开销。当我编写一个逐个下载图像的方法时,这个bug再也没有了。