-
-
Save steipete/1397553 to your computer and use it in GitHub Desktop.
- (void)dealloc { | |
webView_.delegate = nil; // delegate is self here, so first set to nil before call stopLoading. | |
[webView_ stopLoading]; | |
// UIWebView must be released in the main thread, or we get: | |
// 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... | |
// This is less evil than the proposed http://stackoverflow.com/questions/945082/uiwebview-in-multithread-viewcontroller | |
// Calling removeFromSuperview in a dealloc is ugly and evil, but else UIView has a strong reference to UIWebView and our main-release call would be irrelevant. | |
if (![NSThread isMainThread]) { | |
[webView_ performSelectorOnMainThread:@selector(removeFromSuperview) withObject:nil waitUntilDone:YES]; | |
} | |
[webView_ performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:YES]; | |
[super dealloc]; | |
} |
After @anlumo1 'es suggestion, performSelectorOnMainThread immediately calls release if already on main thread, when waitUntilDone is set to YES. (http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/nsobject_Class/Reference/Reference.html)
Still unsure about that removeFromSuperview.
Also - how would I solve this in ARC?
On ARC: maybe settings webView_ to nil in main thread will just work? Something like
dispatch_sync(dispatch_get_main_queue(), ^() {
webView_ = nil;
});
@insanehunter problem is that the block will hold a strong reference to it, so in the end webView will get deallocated in the thread the block was created. (i tried that at first)
Oh, that's really tricky then.
__block variables are not retained, so probably this code should work?
__block id this = self;
dispatch_sync(dispatch_get_main_queue(), ^() {
this.webView_ = nil;
});
Anyway, I should go and read on blocks and GCD.
__block will be retained under ARC - Apple changed this behavior. I could use __weak, but that's more overhead, and I'm not sure what other implications this might would have. (or __unsafe_unretained combined with a CFRetain/CFRelease? feels very hacky...)
Super thanks man.. You saved my a**..
@NSElvis - if i call stopLoading first, couldn't this maybe lead to calling one of my delegate methods within the dealloc? (if the dealloc is on another thread and then context switches...)?