微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

iphone – 令人沮丧的UIWebView委托崩溃问题

我创建了一个运行完美的ARC应用程序.它有一个UINavigationController,我用它来浏览视图,一切运行正常.

我正在将应用程序转换为iPad,我决定将其中一个视图显示为popover. (我不喜欢UIPopoverController所以我创建了自己的基本弹出窗口).它被添加到视图中如下..

MyViewController *hotelinf = [[MyViewController alloc]
initWithNibName:@"MyViewController_iPad" bundle:nil];

[self.view addSubview:hotelinf.view];

该视图作为子视图添加正常.我正在添加的视图包含一个UIWebView,其中包含通常的委托方法,但是当视图尝试访问其中一个委托时,它只会崩溃.

*** -[MyViewController respondsToSelector:]: message sent to deallocated instance 0x7917b90

具体来说,它崩溃在这条线上..

[self.webView loadHTMLString:stringResponse baseURL:nil];

我已经多次将视图(和UINavigationControllers)显示为subViews而没有任何问题,尽管它们都没有包含UIWebView委托.我猜我必须设置我的UIViewController istance的委托,但我不知道如何.值得注意的是,如果我在现有的UINavigationController中推送视图,它会调用并加载HTML,这肯定意味着它与视图本身的代码无关.

任何帮助将不胜感激!这是代码(除了上面显示控制器)..

.H

@interface MyViewController : UIViewController <UIWebViewDelegate,UIActionSheetDelegate> {

//Unrelated IBOutlets

}


@property (nonatomic,strong) UIWebView *webView;

@end

.M

@implementation MyViewController
@synthesize webView;

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.webView = [[UIWebView alloc]initWithFrame:CGRectMake(317,283,393,354)];
    self.webView.delegate = self;
    [self.view addSubview:self.webView];

    [NSThread detachNewThreadSelector:@selector(getHTMLString) toTarget:self withObject:nil];  
}

-(void)getHTMLString {

    @autoreleasepool {
        //Download a valid HTML String
        [self performSelectorOnMainThread:@selector(loadHTML) withObject:nil waitUntilDone:NO];
    }
}

- (void)viewDiddisappear:(BOOL)animated
{
    [super viewDiddisappear:animated];
    self.webView = nil;
}

-(void)loadHTML {


    self.webView.opaque = NO;
    self.webView.backgroundColor = [UIColor clearColor];
    if ([stringResponse isEqualToString:@""]) {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Could not connect to XXXXX.com. Please verify you are connected to a working 3G/WIFI Network." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alert show];

    } else {
        //it crashes here only when loaded as a subview - the first access to the delegate
        [self.webView loadHTMLString:stringResponse baseURL:nil];
    }   
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
}


- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
}

- (void)webViewDidFinishLoad:(UIWebView *)webView {

        [self stopIndicator];
} 

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{

    if (error.code == NSURLErrorCancelled) return; // this is Error -999
    [self stopIndicator];

    // report the error inside the webview
    Nsstring* errorString = [Nsstring stringWithFormat:
                             @"<html><center><font size=+10              color='black' face='Helvetica'>An error occurred:<br>%@</font></center></html>",error.localizedDescription];
    [self.webView loadHTMLString:errorString baseURL:nil];

    UIAlertView *alert = [[UIAlertView alloc]
                          initWithTitle:@"Cannot load URL."
                          message:@"You have a connection failure. Please    verify you are connected to a WIFI or 3G enabled Network."
                          delegate:self cancelButtonTitle:@"Ok"     otherButtonTitles:nil];
    [alert show];



}

@end

解决方法

该问题与UIWebView无关,而与您的控制器类无关.确实,

MyViewController *hotelinf = [[MyViewController alloc]
   initWithNibName:@"MyViewController_iPad" bundle:nil];

[self.view addSubview:hotelinf.view];

您正在分配控制器并将其分配给局部变量;然后将控制器的视图作为子视图添加到当前视图中.这样做,该视图被保留,但控制器对象本身会发生什么?你发布了吗?或者它泄漏(因为它被分配给局部变量)?

这可能解释了为什么稍后调用respondsToSelector方法时,控制器已被解除分配…

解决这个问题的方法是在主控制器类中创建一个属性或ivar,并在其中存储MyViewController.不要忘记以dealloc发布它.

我还会建议另一件事.在:

- (void)viewDiddisappear:(BOOL)animated
{
    [super viewDiddisappear:animated];
    self.webView = nil;
}

在释放视图之前将webView委托设置为nil:

- (void)viewDiddisappear:(BOOL)animated
{
    [super viewDiddisappear:animated];
    self.webView.delegate = nil;
    self.webView = nil;
}

我还可能会查看您在viewDiddisappear中发布webView的原因.另一方面,您在viewDidLoad中分配它.这种不对称是危险的,因为每当主视图消失(出于任何原因)时,webView将被删除,当视图重新出现时,它就不再存在了.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐