6

同じことを繰り返し言っているたくさんのメッセージを読みました。NSURLConnectionを使用すると、デリゲートメソッドは呼び出されません。Appleのドキュメントが不完全で、非推奨のメソッドを参照していることは理解しています。これは残念ですが、解決策が見つからないようです。

リクエストのコードはそこにあります:

// Create request
NSURL *urlObj = [NSURL URLWithString:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:urlObj cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:30];
[request setValue:@"gzip" forHTTPHeaderField:@"Accept-Encoding"];

if (![NSURLConnection canHandleRequest:request]) {
    NSLog(@"Can't handle request...");
    return;
}

// Start connection
dispatch_async(dispatch_get_main_queue(), ^{
    self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES]; // Edited
});

...そしてdelegateメソッドのコードはここにあります:

- (void) connection:(NSURLConnection *)_connection didReceiveResponse:(NSURLResponse *)response {
    NSLog(@"Receiving response: %@, status %d", [(NSHTTPURLResponse*)response allHeaderFields], [(NSHTTPURLResponse*) response statusCode]);
    self.data = [NSMutableData data];
}

- (void) connection:(NSURLConnection *)_connection didFailWithError:(NSError *)error {
    NSLog(@"Connection failed: %@", error);
    [self _finish];
}

- (void) connection:(NSURLConnection *)_connection didReceiveData:(NSData *)_data {
    [data appendData:_data];
}

- (void)connectionDidFinishDownloading:(NSURLConnection *)_connection destinationURL:(NSURL *) destinationURL {
    NSLog(@"Connection done!");
    [self _finish];
}

ここではエラーチェックはそれほど多くありませんが、いくつか確認しました。

  • 何が起こっても呼び出されることdidReceiveDataはないので、データは取得されません
  • ...しかし、データは転送されます(私はを使用してチェックしましたtcpdump
  • ...そして他のメソッドは正常に呼び出されます。
  • NSURLConnectionDownloadDelegateの代わりにを使用するとNSURLConnectionDataDelegate、すべてが機能しますが、ダウンロードしたファイルを保持できません(これは既知のバグです)
  • 不正なメモリ管理によって、要求が完了する前に割り当てが解除されない
  • インターネット上のどこかで標準のHTMLページをURLとして使用しても、何も変わりません。
  • リクエストはメインキューからキックオフされます

最終的に、これらのリクエストは自分のライブラリに含まれることになっているため、サードパーティのライブラリを使用したくありません。依存関係を最小限に抑えたいと思います。必要に応じて直接使用しますCFNetworkが、それはあなたが知っていることで大きな苦痛になります。

あなたが何か考えを持っているなら、それは大いに役立つでしょう。ありがとう!

4

4 に答える 4

13

私は同じ問題に遭遇しました。非常に煩わしいですが、このメソッドを実装すると、次のようになります。

- (void)connectionDidFinishDownloading:(NSURLConnection *)connection destinationURL:(NSURL *)destinationURL

Then connection:didReceiveData: will never be called. You have to use connectionDidFinishLoading: instead... Yes, the docs say it is deprecated, but I think thats only because this method moved from NSURLConnectionDelegate into NSURLConnectionDataDelegate.

于 2013-03-15T18:56:28.057 に答える
2

sendAsynchronousRequestメソッドを使用するのが好きです。接続中の情報は少なくなりますが、コードははるかにクリーンになります。

    [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
        if (data){
            //do something with data
        }
        else if (error)
            NSLog(@"%@",error);
    }];

Appleから:

デフォルトでは、接続は、作成時にデフォルトモードで現在のスレッドにスケジュールされます。initWithRequest:delegate:startImmediately:メソッドを使用して接続を作成し、startImmediatelyパラメーターにNOを指定すると、startメソッドで開始する前に、別の実行ループまたはモードで接続をスケジュールできます。複数の実行ループとモードで接続をスケジュールすることも、複数のモードで同じ実行ループで接続をスケジュールすることもできます。

[NSRunLoop currentRunLoop]で明示的に実行する理由がない限り、次の2行を削除できます。

[connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
[connection start];

またはモードをNSDefaultRunLoopModeに変更します

于 2012-07-10T19:53:13.977 に答える
1

NSURLConnection API says " ..delegate methods are called on the thread that started the asynchronous load operation for the associated NSURLConnection object."

Because dispatch_async will start new thread, and NSURLConnection will not pass to that other threat the call backs, so do not use dispatch_async with NSURLConnection.

You do not have to afraid about frozen user interface, NSURLConnection providing only the controls of asynchronous loads.

ダウンロードするファイルがさらにある場合は、最初のターンで接続の一部を開始し、後でそれらが終了すると、connectionDidFinishLoading:メソッドで新しい接続を開始できます。

int i=0;
for (RetrieveOneDocument *doc in self.documents) {

    if (i<5) {
         [[NSURLConnection alloc] initWithRequest:request delegate:self];
        i++;
    }
}

..

-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    ii++;
    if(ii == 5) {
         [[NSURLConnection alloc] initWithRequest:request delegate:self];
        ii=0;
    }
}
于 2013-04-27T06:40:25.353 に答える
0

考えられる理由の1つは、発信NSURLRequestがのを設定されていること-HTTPMethodですHEAD。しかし、偶然にそれを行うのは非常に困難です!

于 2012-11-05T15:31:52.737 に答える