Асинхронно Api вызывает и возвращает данные вне блока - PullRequest
0 голосов
/ 05 ноября 2018

Я не понимаю, почему я получаю нулевой массив вне кода блока, хотя я использую ключевое слово __block в моем массиве.

Я успешно получаю данные из API бэкэнда со следующим кодом

`-(void)getJsonResponse:(NSString *)urlStr success:(void (^)(NSArray *responseDict))success failure:(void(^)(NSError* error))failure
{
    NSURLSession *session = [NSURLSession sharedSession];
    NSURL *url = [NSURL URLWithString:urlStr];

    // Asynchronously API is hit here
    NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url
                                            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                              //  NSLog(@"%@",data);
                                                if (error)
                                                    failure(error);
                                                else {
                                                    NSArray *json  = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
                                                   // NSLog(@"%@",json);
                                                    success(json);
                                                }
                                            }];
    [dataTask resume];    // Executed First
}`

Тогда в моей функции для возврата данных я использую следующее

 `- (NSArray *)get_data:(NSDictionary *)credentials{

    NSString *urlStr =[ NSString stringWithFormat:@"http://test.com %@",credentials];
   __block NSArray *jsonArray= [[NSArray alloc]init];
    [self getJsonResponse:urlStr success:^(NSArray *responseArray) {
        jsonArray = responseArray;
        NSLog(@"%@",responseArray);
    } failure:^(NSError *error) {
        // error handling here ...
    }];
     NSLog(@"%@",jsonArray);
    return jsonArray;
}
`

Проблема здесь в том, что, хотя я успешно получаю данные в блоке getJsonResponse, но когда я пытаюсь вернуть массив данных ответа в виде функции return, я получаю нулевое значение для jsonArray. Я думал, что присвоение __block перед jsonArray должно сохранить назначение данных в коде блока?

Второй подход заключается не в использовании асинхронного способа, подобного следующему

`- (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error
{

    NSError __block *err = NULL;
    NSData __block *data;
    BOOL __block reqProcessed = false;
    NSURLResponse __block *resp;

    [[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable _data, NSURLResponse * _Nullable _response, NSError * _Nullable _error) {
        resp = _response;
        err = _error;
        data = _data;
        reqProcessed = true;
    }] resume];

    while (!reqProcessed) {
        [NSThread sleepForTimeInterval:0];
    }

    *response = resp;
    *error = err;
    return data;
}`

Таким образом, он блокирует основной поток, ожидая данных.

1 Ответ

0 голосов
/ 05 ноября 2018

Я бы предложил использовать тот же подход getJsonResponse для вашей функции get_data:

- (void)get_data:(NSDictionary *)credentials finish:(void(^)(NSArray *data))finish{

    NSString *urlStr =[ NSString stringWithFormat:@"http://test.com %@",credentials];
   __block NSArray *jsonArray= [[NSArray alloc]init];
    [self getJsonResponse:urlStr success:^(NSArray *responseArray) {
        jsonArray = responseArray;
        if (finish) {
            finish(jsonArray);
        }
    } failure:^(NSError *error) {
        // error handling here ...
    }];
}
...