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再也没有了
答案 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再也没有了。