点击iPhone中的后退按钮,应用程序崩溃

时间:2012-08-21 12:20:17

标签: iphone ipad uiwebview nsurlconnection back-button

我是iPhone新手,

我目前正在开发一款iPhone应用程序,并且我已经实现了从网址下载文件的功能。我创建了UIWebView,当用户点击webview中的下载链接时,下载将开始,我将该文件保存到文档目录中的指定文件夹,这一切都在我的{{1}中工作正常} ..

但在此之后,当我按下后退按钮导航到我的Second View时,我的应用程序崩溃了...显示First view

EXC_BAD_ACCESS

我能够看到上面-(void)viewWillAppear:(BOOL)animated{ //Doing some operation and it works fine... NSLog(@"viewWillAppear in First View......."); } -(void)viewDidAppear:(BOOL)animated{ NSLog(@"viewDidAppear in First View......."); } 当我按下后退按钮但我的应用程序在1秒或半秒后崩溃。

以下是Log中的代码,

Second View

我的日志显示:- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { [receivedData setLength:0]; } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data1 { [receivedData appendData:data1]; } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { NSLog(@"Succeeded! Received %d bytes of data",[receivedData length]); DirPath=[self applicationDocumentsDirectory]; NSLog(@"DirPath=%@",DirPath); [receivedData writeToFile:DirPath atomically:YES]; UIAlertView* Alert = [[UIAlertView alloc] initWithTitle:@"Download Complete !" message:nil delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [Alert show]; [Alert release]; // release the connection, and the data object [connection release]; [receivedData release]; } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error1 { [connection release]; [receivedData release]; // inform the user NSLog(@"Connection failed! Error - %@ %@", [error1 localizedDescription], [[error1 userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]); } - (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType { url = [request URL]; //CAPTURE USER LINK-CLICK. DirPath=[self applicationDocumentsDirectory]; Durl=[[url absoluteString]copy]; //Checking for Duplicate .FILE at downloaded path.... BOOL success =[[NSFileManager defaultManager] fileExistsAtPath:path]; lastPath=[[url lastPathComponent] copy]; if (success) //if duplicate file found... { UIAlertView* Alert = [[UIAlertView alloc] initWithTitle:@"This FILE is already present in Library." message:@"Do you want to Downlaod again ?" delegate:self cancelButtonTitle:nil otherButtonTitles:@"Yes",@"No",nil]; [Alert show]; [Alert release]; } else //if duplicate file not found directly start download... { // Create the request. NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:Durl] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0]; // create the connection with the request and start loading the data NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self]; if (theConnection) { // Create the NSMutableData to hold the received data. receivedData = [[NSMutableData data] retain]; } else { NSLog(@"Inform the user that the connection failed."); } return YES; } - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { if (buttonIndex == 0) { // Create the request. NSURLRequest *theRequest1=[NSURLRequest requestWithURL:[NSURL URLWithString:Durl] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0]; // create the connection with the request and start loading the data NSURLConnection *theConnection1=[[NSURLConnection alloc] initWithRequest:theRequest1 delegate:self]; if (theConnection1) { // Create the NSMutableData to hold the received data. receivedData = [[NSMutableData data] retain]; } else { NSLog(@"Inform the user that the connection failed."); } } else {[alertView dismissWithClickedButtonIndex:1 animated:TRUE];} } - (void)webView:(UIWebView *)webview didFailLoadWithError:(NSError *)error1 { NSLog(@"didFailLoadWithError: %@; stillLoading:%@", error1,(webview.loading?@"NO":@"YES")); }

didFailLoadWithError: Error Domain=WebKitErrorDomain Code=102 "Frame load interrupted" UserInfo=0x6b34910 {NSErrorFailingURLKey=MY_URL, NSErrorFailingURLStringKey=MY_URL, NSLocalizedDescription=Frame load interrupted}; stillLoading:YES

任何帮助都会得到满足。

5 个答案:

答案 0 :(得分:1)

首先,你要在这里做的事情,你不应该从视野中做。与Model网络服务进行通信的代码最好在Model类中,而不是在视图中:

http://developer.apple.com/library/ios/#DOCUMENTATION/Cocoa/Conceptual/CocoaFundamentals/CocoaDesignPatterns/CocoaDesignPatterns.html

现在,您最终可能会遇到连接调用您在视图中实现的委托方法的情况,但是当您单击后退按钮时,您的视图已经被释放。

此外,您不维护指向您在webView:shouldStartLoadWithRequest:方法中创建的NSURLConnection实例的指针。相反,您依赖于调用connectionDidFinishLoading:方法来再次释放连接对象。这样你就不会确定你是否正在释放它,或者你是否可能过度释放它,如果多次调用该方法。

在视图类中使用实例变量来保存指向连接对象的指针,这样您就可以在必要时(当您不再使用它时,或视图消失时)释放它。确保在删除视图([连接取消])之前也取消查询。

答案 1 :(得分:1)

我认为你发布错误的东西......考虑一下,

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error1

无需释放连接,receivedData

在dealloc块中,添加此代码

- (void) dealloc
  {
      if (theConnection)
      { 
           [theConnection release], theConnection = nil;
      }

      if (receivedData)
      { 
           [receivedData release], receivedData = nil;
      }
  }

添加,如果您使用相同的webView创建多个连接,则添加

if (theConnection)
{ 
      [theConnection release], theConnection = nil;
}

if (receivedData)
{ 
     receivedData release], receivedData = nil;
}

在分配URLConnection和NsMutableData之前,这是一个阻止内存泄漏的措施。最好有一个活动微调器,直到事件完成。

答案 2 :(得分:1)

尝试在secondView Controller类中添加它

- (void)viewWillDisappear
{
    if ([webView isLoading])
        [webView stopLoading];

    [webView setDelegate:nil];
}

或者在第二个视图的后退按钮操作中添加它

答案 3 :(得分:0)

在添加了WebView的第一个视图的dealloc方法中,设置webView = nil的委托。 有一段时间这可能是崩溃的原因。

答案 4 :(得分:0)

做两件事:

  1. 如果您要释放连接和数据(receivedData),请将其设置为nil。
  2. 在你的dealloc方法中,[webView stopLoading]在发布webView之前。