UIWebView 发布导致崩溃
Posted
技术标签:
【中文标题】UIWebView 发布导致崩溃【英文标题】:UIWebView release causes crash 【发布时间】:2012-03-19 18:25:30 【问题描述】:我有一个 UIViewController 子类,它有一个 UIWebView。它将 Web 视图添加为视图的子视图,并在 dealloc 中释放它。以下是相关代码:
#import "MediaVC.h"
@implementation MediaVC
@synthesize file, repository, server, delegate;
- (void)viewDidLoad
[super viewDidLoad];
webView = [[UIWebView alloc] initWithFrame:[[self view] bounds]];
[webView setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
[webView setScalesPageToFit:YES];
[webView setMultipleTouchEnabled:YES];
[[self view] addSubview:webView];
[self displayFile];
[flex release];
[buttonDone release];
[buttonAction release];
- (void)displayFile
if (!mimeString)
[webView loadData:nil
MIMEType:nil
textEncodingName:nil
baseURL:nil];
[SVProgressHUD dismissWithError:@"Can't display this file." afterDelay:2];
else
[[DataCenter sharedInstance] getDataForFile:file
server:server
repository:repository
isThumb:NO
completion:^(NSData *data)
NSString *filenamePath =[NSString stringWithFormat:@"temp.%@", [[file path] pathExtension]];
NSString *docDir = [DataCenter getDocumentsDirectoryPath];
NSString *fullPath = [docDir stringByAppendingPathComponent:filenamePath];
[data writeToFile:fullPath atomically:YES];
[webView loadData:data
MIMEType:[DataCenter mimeTypeForFile:file]
textEncodingName:nil
baseURL:nil];
if (!data)
[SVProgressHUD dismissWithError:@"Error!"];
else
[SVProgressHUD dismiss];
progress:^(float progress)
[SVProgressHUD setFloat:progress];
];
- (void)dealloc
[buttonNext release];
[buttonBack release];
//[webView release]; ---CRASH HAPPENS IF I UNCOMMENT THIS LINE
[super dealloc];
@end
应用程序在 [super dealloc] 处崩溃;。我有 NSZombieEnabled,它没有给我任何关于“发送到已释放实例的错误......”的错误。我确实发现,如果我注释掉[webView release],
,就不会发生崩溃。
我检查了一下,我只分配一次 UIWebView 并释放一次。
更新请在下面找到完整的课程。正如我所说,那门课有很多不相关的东西,我找不到任何问题,也许你们找到了一些东西:
#import "MediaVC.h"
#import "DataCenter.h"
#import "SVProgressHUD.h"
#import "File.h"
@implementation MediaVC
@synthesize file, repository, server, delegate;
- (void)viewDidLoad
[super viewDidLoad];
UIBarButtonItem *buttonDone = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:@selector(done)];
UIBarButtonItem *buttonAction = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction
target:self
action:@selector(action:)];
buttonNext = [[UIBarButtonItem alloc] initWithTitle:@"Next"
style:UIBarButtonItemStyleDone
target:self
action:@selector(next)];
buttonBack = [[UIBarButtonItem alloc] initWithTitle:@"Back"
style:UIBarButtonItemStyleDone
target:self
action:@selector(back)];
UIBarButtonItem *flex = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:nil];
[[self navigationItem] setLeftBarButtonItem:buttonDone];
[[self navigationItem] setRightBarButtonItem:buttonAction];
[[self navigationController] setToolbarHidden:NO];
[self setToolbarItems:[NSArray arrayWithObjects:buttonBack, flex, buttonNext, nil] animated:YES];
webView = [[UIWebView alloc] initWithFrame:[[self view] bounds]];
[webView setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
[webView setScalesPageToFit:YES];
[webView setMultipleTouchEnabled:YES];
[[self view] addSubview:webView];
[self displayFile];
[flex release];
[buttonDone release];
[buttonAction release];
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
return YES;
- (void)done
[delegate doneMediaVC:self];
- (void)action:(id)button
NSString *filenamePath = [file path];
NSString *docDir = [DataCenter getDocumentsDirectoryPath];
NSString *fullPath = [docDir stringByAppendingPathComponent:filenamePath];
NSURL *url = [NSURL fileURLWithPath:fullPath];
UIDocumentInteractionController *c = [UIDocumentInteractionController interactionControllerWithURL:url];
BOOL success = [c presentOpenInMenuFromBarButtonItem:buttonBack animated:YES];
if (!success)
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error" message:@"An application cannt be found to open this file"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil, nil];
[alertView show];
[alertView release];
- (void)displayFile
[self setTitle:[file name]];
[SVProgressHUD showInView:[[self navigationController] view]
status:@"Loading..."
networkIndicator:YES
progress:YES];
NSString *mimeString = [DataCenter mimeTypeForFile:file];
if (!mimeString)
[webView loadData:nil
MIMEType:nil
textEncodingName:nil
baseURL:nil];
[SVProgressHUD dismissWithError:@"Can't display this file." afterDelay:2];
else
[[DataCenter sharedInstance] getDataForFile:file
server:server
repository:repository
isThumb:NO
completion:^(NSData *data)
NSString *filenamePath =[NSString stringWithFormat:@"temp.%@", [[file path] pathExtension]];
NSString *docDir = [DataCenter getDocumentsDirectoryPath];
NSString *fullPath = [docDir stringByAppendingPathComponent:filenamePath];
[data writeToFile:fullPath atomically:YES];
[webView loadData:data
MIMEType:[DataCenter mimeTypeForFile:file]
textEncodingName:nil
baseURL:nil];
if (!data)
[SVProgressHUD dismissWithError:@"Error!"];
else
[SVProgressHUD dismiss];
progress:^(float progress)
[SVProgressHUD setFloat:progress];
];
if (![delegate canGoNext:self currentFile:file])
[buttonNext setEnabled:NO];
else
[buttonNext setEnabled:YES];
if (![delegate canGoPrevious:self currentFile:file])
[buttonBack setEnabled:NO];
else
[buttonBack setEnabled:YES];
- (void)back
[self setFile:[delegate getPreviousFileForMediaVC:self currentFile:file]];
[self displayFile];
- (void)next
[self setFile:[delegate getNextFileForMediaVC:self currentFile:file]];
[self displayFile];
- (void)dealloc
[buttonNext release];
[buttonBack release];
//[webView release];
[super dealloc];
@end
谢谢!
【问题讨论】:
webview变量的分配和释放没有问题。也许您创建了一个映射到 webview 的保留属性?如果不是,那么一定是其他原因导致了崩溃。 @PhilippeLeybaert 查看丢失的代码量,实际代码可能有很多错误。 我知道,这就是为什么我说变量的分配/释放没有问题,可能是其他原因导致了问题。 @PhilippeLeybaert 很好,因为您应该在释放 webview 变量之前将委托设置为 nil。 我刚刚在原始问题中粘贴了 amy complete class。 【参考方案1】:您在文档中看到这一行了吗?
重要事项在发布您拥有的 UIWebView 实例之前 设置委托,您必须首先将其委托属性设置为 nil。这 例如,可以在您的 dealloc 方法中完成。
您的“相关代码”没有显示您设置委托,但话又说回来,您的相关代码根本不完整。 (flex?buttonDone?buttonAction?)
如果您想要一个好的答案,请分享所有代码。
【讨论】:
我刚刚在原始问题中粘贴了 amy complete class。以上是关于UIWebView 发布导致崩溃的主要内容,如果未能解决你的问题,请参考以下文章
WebCore 的崩溃是不是意味着它必然与 UIWebView 相关?
UIWebView iOS 5:WebKit/JavaScriptCore 崩溃
iOS 5 - 空白 UIWebView 在 ViewDidAppear 之前导致长时间延迟