0

私はiPhoneを初めて使用しますが、

私は現在iPhoneアプリを開発しており、URLからファイルをダウンロードする機能を実装しています。UIWebViewを作成しました。ユーザーがのダウンロードリンクをクリックするとwebview、ダウンロードが開始され、そのファイルがドキュメントディレクトリの指定されたフォルダに保存されます。これはすべて正常に機能してい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.......");
}

Log戻るボタンを押すと上記が表示されますが、1秒または0.5秒後にアプリがクラッシュします。

これが私のコードです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

DirPath=/Users/krunal/Library/Application Support/iPhone Simulator/5.0/Applications/FCDDDE83-A9B3-4C14-A56C-E8C5FCE7F5C4/Documents/DownloadedFile.epub

どんな助けでも適用されます。

4

5 に答える 5

1

まず第一に、あなたがここでやろうとしていることは、視点からやるべきではありません。ネットワークサービスと通信しているコードは、ビューではなく、モデルクラスの方が適しています。

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

これで、接続がビューに実装したデリゲートメソッドを呼び出しているが、戻るボタンをクリックしたときにビューがすでに解放されている状況に陥ることがあります。

また、webView:shouldStartLoadWithRequest:メソッドで作成したNSURLConnectionインスタンスへのポインターを維持しません。代わりに、connectionDidFinishLoading:メソッドが呼び出されて、接続オブジェクトを再度解放することに依存します。この方法では、リリースするのか、リリースしすぎているのか、メソッドが複数回呼び出されているのかがわかりません。

ビュークラスでインスタンス変数を使用して接続オブジェクトへのポインタを保持し、必要に応じて(使用しなくなったとき、またはビューがなくなったときに)解放できるようにします。ビューを削除する前に、必ずクエリをキャンセルしてください([接続キャンセル])。

于 2012-08-21T12:52:04.397 に答える
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を割り当てる前に、これはメモリリークを防ぐための手段です。そして、イベントが完了するまでアクティビティスピナーを持っている方が良いです。

于 2012-08-23T16:15:22.300 に答える
1

これをsecondViewControllerクラスに追加してみてください

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

    [webView setDelegate:nil];
}

または、secondViewの戻るボタンアクションにこれを追加します

于 2012-08-24T18:34:35.177 に答える
0

WebViewが追加された最初のビューのdeallocメソッドで、webViewのデリゲートをnilに設定します。いつかこれがクラッシュの原因になることがあります。

于 2012-08-21T17:36:34.217 に答える
0

2つのことを行います。

  1. 接続とデータ(receivedData)を解放する場合は常に、nilに設定します。
  2. あなたのdeallocメソッドで、webViewをリリースする前に[webViewstopLoading]。
于 2012-08-24T13:05:34.967 に答える