2

したがって、ViewController が読み込まれるたびに、サーバーにアップロードします。ただし、問題があるようです。かなりの数の非同期リクエストがある場合、アプリがセミクラッシュする可能性があります。つまり、リクエストは通過せず、他のリクエスト (別のスレッドにある) は処理されないということです。その上、キーボードは非常に遅くなります (奇妙なことに私は知っています)。とにかく、それが原因で他のネットワーク要求が送信されないことを考えると、これは深刻な問題です。私が奇妙に思うのは、アップロード リクエストの数がダウンロード リクエストの数と同じであることです (アップロードは何もせず、通常の http リクエストを行うだけです)。これが私のコードです:

- (void)serverUploadAll:(myEntity *)send
{  
    NSMutableString *urlString = [[NSMutableString alloc] initWithString:ServerApiURL];
    NSString *addTargetUrl = [NSString stringWithFormat:@"/addtarget?deviceToken=%@&appVersion=%@&targetId=%@", postToServer.deviceToken, postToServer.appVersion, send.Id];
    [urlString appendString:addTargetUrl];

    NSURL *url = [NSURL URLWithString:urlString];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    [NSURLConnection sendAsynchronousRequest:request queue:queueTwo completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
        //NSLog(@"response=%@", response);
        //NSLog(@"data=%@", data);
        //NSLog(@"error=%@", error);
    }];

}

上記のコードは、データベースが循環するときに呼び出され、かなりの量の呼び出し (つまり 120 回以上) がある場合に問題が発生します。私のダウンロード リクエストは実際には AFNetworking を使用して行われているため、効率的に動作するのかもしれません。とにかく、要約すると、上記のコードが複数回呼び出されると、なぜジャムして停止するのでしょうか?

助けてくれてありがとう、本当に感謝しています。
よろしく、
マイク

更新:したがって、runmad による素晴らしい回答のおかげで、私は AFNetworking アプローチを使用していますが、このエラーでクラッシュします-[AFHTTPRequestOperation _propertyForKey:]: unrecognized selector sent to instance。それが機能しない理由がわかりません。ここに私のコードがあります:

- (void)cycleThroughEntries
{
MyEntity *myEntity;
NSMutableArray *urlRequests;
urlRequests = [[NSMutableArray alloc] init];

for (id i in fetchedResultsController.fetchedObjects) {
    myEntity = i;
    NSMutableString *urlString = [[NSMutableString alloc] initWithString:ServerApiURL];
    NSString *addTargetUrl = [NSString stringWithFormat:@"/addtarget?deviceToken=%@&appVersion=%@&targetId=%@", postToServer.deviceToken, postToServer.appVersion, myEntity.Id];
    [urlString appendString:addTargetUrl];
    //NSLog(@"URL sent is: %@", urlString);
    NSURL *url = [NSURL URLWithString:urlString];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    [urlRequests addObject:requestOperation];
}

AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:@""]];

[client enqueueBatchOfHTTPRequestOperationsWithRequests:urlRequests
                                        progressBlock:^(NSUInteger numberOfCompletedOperations, NSUInteger totalNumberOfOperations) {

                                            NSLog(@"%d / %d", numberOfCompletedOperations, totalNumberOfOperations);

                                        }
                                        completionBlock:^(NSArray *operations) {
                                            NSLog(@"All Done!");
                                        }];

}

何が間違っているのか完全にはわからないので、助けていただければ幸いです。ありがとう。

更新 2:修正済み。の配列を作成するべきではありませんでしAFHTTPRequestOperationsたが、通常のNSURLRequests. 問題が解決しました!!

4

1 に答える 1

4

バックグラウンド スレッドで発生する場合でも、作成できる非同期接続の数には制限があります。同時に 120 以上のネットワーク呼び出しは、特に GET 要求よりも時間がかかるアップロードが含まれている場合は、少しおかしなことに思えます。

リクエストの量を減らすために、サーバーにリクエスト/アップロードする必要があるものを書き直すことを検討することをお勧めします。すべての通話が同時に発生しないようにし、他の通話が完了するまでほとんどの通話を保留にする必要があります。

入力してくださいNSOperationQueue...

すべてのリクエストを処理するマネージャー クラスを作成します。このクラスNSOperationQueueでは、リクエストを追加し続けることができる場所を作成します。ここに良いチュートリアルがあります。同時リクエストの数を設定できます。NSOperationQueue は、キュー内の次のリクエストが現在実行中のリクエストが完了するまで待機するようにします。ネットワーキングを使用すると、多くの面倒な作業が行われます。

AFNetworkingを調べて、すべてのNSOperationQueuesネットワーク呼び出しをキューに入れ、すべてが同時に発生しないようにすることも検討してください。

AFNetworking ではAFHTTPClient、リクエストの設定方法に応じて、次の方法を使用できる場合があります。

- (void)enqueueBatchOfHTTPRequestOperationsWithRequests:(NSArray *)urlRequests
                                          progressBlock:(void (^)(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations))progressBlock
                                        completionBlock:(void (^)(NSArray *operations))completionBlock;

これで始められるはずです:)頑張ってください。

アップデート

必要に応じて、AFNetworking の operationsQueue に操作を追加することもできます。現在まだ実行されていない場合は、必ず開始する必要があります。このようにして、さまざまなタイミングでアプリの他の部分から追加のリクエストを追加できます。操作が実行中またはキュー内にあるかどうかをいつでも確認できます。すばらしいことは、実行中の操作を簡単にキャンセルできることです。ここで見つけることができます。

于 2013-01-29T13:55:35.543 に答える