异步请求 运行 慢 - iOS

Asynchronous request running slowly - iOS

我有一个应用程序可以从服务器下载一组照片。我正在使用异步请求,因为我不想 UI 被阻止。但是,我发现请求非常慢并且需要很长时间才能加载。

我知道您可以将队列类型设置为 [NSOperationQueue mainQueue] 但这只会将异步请求放回主线程,这破坏了首先发出异步请求的全部意义。

有没有办法加快请求速度或者告诉iOS:"Run this request in the background, but do it ASAP, don't leave it till the end of the queue"???

这是我的代码:

// Set up the photo request.
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:PHOTO_URL, pass_venue_ID, PHOTO_CLIENT_ID, PHOTO_CLIENT_SECRET]];
    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];

    // Begin the asynchromous image loading.
    [NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {

        if (error == nil) {

            // Convert the response data to JSON.
            NSError *my_error = nil;
            NSDictionary *feed = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&my_error];

            // Check to see if any images exist
            // for this particular place.
            int images_check = [[NSString stringWithFormat:@"%@", [[[feed objectForKey:@"response"] valueForKey:@"photos"] valueForKey:@"count"]] intValue];

            if (images_check > 0) {

                // Download all the image link properties.
                images_prefix = [[[[feed objectForKey:@"response"] valueForKey:@"photos"] valueForKey:@"items"] valueForKey:@"prefix"];
                images_suffix = [[[[feed objectForKey:@"response"] valueForKey:@"photos"] valueForKey:@"items"] valueForKey:@"suffix"];
                images_width = [[[[feed objectForKey:@"response"] valueForKey:@"photos"] valueForKey:@"items"] valueForKey:@"width"];
                images_height = [[[[feed objectForKey:@"response"] valueForKey:@"photos"] valueForKey:@"items"] valueForKey:@"height"];

                // Set the image number label.
                number_label.text = [NSString stringWithFormat:@"1/%lu", (unsigned long)[images_prefix count]];

                // Download up to 5 images.
                images_downloaded = [[NSMutableArray alloc] init];

                // Set the download limit.
                loop_max = 0;

                if ([images_prefix count] > 5) {
                    loop_max = 5;
                }

                else {
                    loop_max = [images_prefix count];
                }

                for (NSUInteger loop = 0; loop < loop_max; loop++) {

                    // Create the image URL.
                    NSString *image_URL = [NSString stringWithFormat:@"%@%@x%@%@", images_prefix[loop], images_width[loop], images_height[loop], images_suffix[loop]];

                    // Download the image file.
                    NSData *image_data = [NSData dataWithContentsOfURL:[NSURL URLWithString:image_URL]];

                    // Store the image data in the array.
                    [images_downloaded addObject:image_data];
                }

                // Load the first image.
                [self load_image:image_num];
            }

            else if (images_check <= 0) {

                // error...
            }
        }

        else {

            // error
        }
    }];

丹,谢谢你的时间。

我认为你的问题不是请求 运行 慢,而是你正在更新不在主线程上的 UI 元素,包围任何 UI 更新(比如将文本设置为标签)与

dispatch_sync(dispatch_get_main_queue(), ^{
        <#code#>
});

正如 Fonix 所说,这并不是 iOS 响应缓慢,而是 dataWithContentsOfURL 在后台线程中不起作用。 Apple 的建议是您应该将 NSURLConnection 与委托异步使用 - didReceiveResponse - didReceiveData

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:theURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:_mAuthenticationTimeoutInterval];

在这些方法中,您也可以使用数据块。

如果您确实希望这些多个下载更快,您应该使用 NSOperationQueue 并行下载。可以参考enter link description here

我认为一个好的解决方案可能是将 AFNetworking 与 NSOperation 结合使用,检查我编写的这段代码以异步执行多个操作

NSMutableArray *operations = [[NSMutableArray alloc] init];
for(NSObject *obj in caches) {
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];        
//...set up your mutable request options here

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    operation.responseSerializer = [AFJSONResponseSerializer serializer];
    operation.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"application/json"];
    [operation  setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {

        NSInteger statusCode = operation.response.statusCode;
        if(statusCode==200) {
        }

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"API Call error:%@", error.localizedDescription);
    }];

    [[requestManager operationQueue] addOperation:operation];
    [operations addObject:operation];

    if([operations count] >= MAX_API_CALL) break;
}

[AFHTTPRequestOperation batchOfRequestOperations:operations progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations) {
} completionBlock:^(NSArray *operations) {

    NSError *error;
    for (AFHTTPRequestOperation *op in operations) {
        if (op.isCancelled){
        }
        if (op.responseObject){
            // process your responce here
        }
        if (op.error){
            error = op.error;
        }
    }
}];