应用程序在[UIWebView webView:didReceiveTitle:forFrame:]崩溃

时间:2011-05-25 04:11:14

标签: iphone objective-c ios4 uiwebview

我正在实现一个简单的应用内浏览器。在我的家庭视图(UITableViewController)中,我有类似的内容:

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

        WebViewController *webViewController = [[WebViewController alloc] init];
        switch (indexPath.row) {
            case 0:
                webViewController.stringURL = @"http://www.google.com";
                break;
            case 1:
                webViewController.stringURL = @"http://www.bing.com";
                break;
            default:
                webViewController.stringURL = @"http://stackoverflow.com"; 
                break;
        }

        [self.navigationController pushViewController:webViewController animated:YES];
        [webViewController release];
    }

在我的主视图和webViewController之间反复导航几次后,应用崩溃了

WebViewController课程内,我只有[UIWebView *webView][UIActivityIndicatorView *activityIndicator]。两者都具有属性nonatomic, retain。这是实施。

        #import "WebViewController.h"
        @implementation WebViewController
        @synthesize webView, activityIndicator, stringURL;

        - (void)dealloc
        {
            [self.webView release];
            self.webView.delegate = nil;
            [self.activityIndicator release]; 
            [super dealloc];
        }

        -(void)loadView {
            UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
            self.view = contentView;    

            CGRect webFrame = [[UIScreen mainScreen] applicationFrame];
            webFrame.origin.y = 0.0f;
            self.webView = [[UIWebView alloc] initWithFrame:webFrame];
            self.webView.backgroundColor = [UIColor blueColor];
            self.webView.scalesPageToFit = YES;
            self.webView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
            self.webView.delegate = self;
            [self.view addSubview: self.webView];
            [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.stringURL]]];

            self.activityIndicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
            self.activityIndicator.frame = CGRectMake(0.0, 0.0, 30.0, 30.0);
            self.activityIndicator.center = self.view.center;
            [self.view addSubview: self.activityIndicator];
        }

        - (void)viewDidLoad
        {   
            [super viewDidLoad];
            [self loadView];
        }

        - (void)webViewDidStartLoad:(UIWebView *)webView
        {
            // starting the load, show the activity indicator in the status bar
            [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
            [activityIndicator startAnimating];
        }

        - (void)webViewDidFinishLoad:(UIWebView *)webView
        {
            // finished loading, hide the activity indicator in the status bar
            [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
            [activityIndicator stopAnimating];
        }

        @end


我刚刚使用 Zombies模板在Instruments中运行我的应用程序,其中显示-[UIWebView webView:didReceiveTitle:forFrame:]是Zombie调用。但我仍然无法弄清楚究竟是什么问题。

(如果需要,请下载trace

非常感谢任何帮助!


[更新]:

  1. 正如@ 7KV7和@David指出的那样,我的dealloc函数中存在一个明显的错误。在我发布self.webView.delegate=nil;之前,我应先致电self.webView。对于那个很抱歉。不幸的是,在我修复它之后,应用程序仍以同样的方式崩溃。
  2. 如果我从第一个代码块中删除 [webViewController release]; ,则崩溃实际上已经消失。但很明显,会有内存泄漏。

5 个答案:

答案 0 :(得分:3)

首先,移除loadView中对viewDidLoad的号召。当框架找不到XIB文件中提供的视图时,框架将调用该方法。其次,你的loadView充满了内存泄漏。每次调用方法时,您都在分配,初始化和保留对象。因此,您将获得所有权两次并在dealloc中仅发布一次。

未正确释放对象。你应该做像alloc-init-autorelease这样的事情来解决这个问题。接下来的事情是,每次控制器加载时,由于您调用loadView,您最终会创建两个Web视图对象和两个请求。当您重新分配时,您将失去对其中一个的引用。这里,标题中提到的问题就在于此。您无法重置将控制器作为委托的Web视图对象的委托。想象一下,您离开后不久就会完成一项请求。这里的消息将转到僵尸对象。这是一个很好的例子,说明为什么需要nil代理人。

答案 1 :(得分:2)

- (void)dealloc
{
self.webView.delegate = nil;
[self.webView release];
[self.activityIndicator release]; 
[super dealloc];
}

试试这个dealloc。您正在发布webview,然后将delegate设置为nil。您应该首先将delegate设置为nil,然后将release设置为{{1}}。希望这能解决问题。

答案 2 :(得分:1)

我认为正在发生的事情是你在页面仍在加载时返回,因此控制器被取消分配,然后webview完成加载。 尝试在viewDidUnload方法中调用[webView stopLoading]以确保不会发生这种情况。

答案 3 :(得分:0)

不知道这是否是你问题的原因,但这绝对是错误的:

[self.webView release];
self.webView.delegate = nil;

发布后,您无法(安全地)引用self.webView

答案 4 :(得分:0)

不是推送webViewController,而是将其视图添加到self.view。 不要叫[self loadView];在viewDidLoad。