Как устранить неполадки сбоя dispatch_group_leave - PullRequest
0 голосов
/ 13 января 2020

Я знаю, что dispatch_group_leave вызовы должны быть сбалансированы с dispatch_group_enter. Вот блок кода, в котором происходит мой cra sh (случайно, не всегда)

            dispatch_group_t group = dispatch_group_create();
            dispatch_group_enter(group);
            [self getVibrationHistorySuccess:^(NSArray<VibrationPointDTO *> *vibrationPoints) {
                self.vibrationPoints = vibrationPoints;
                dispatch_group_leave(group);
            } failure:^(NSError *error) {
                dispatch_group_leave(group);
            }];

            dispatch_group_enter(group);
            [self getTemperatureHistorySuccess:^(NSArray<TemperatureSetDTO *> *sets) {
                self.temperatureSets = sets;
                dispatch_group_leave(group);
            } failure:^(NSError *error) {
                dispatch_group_leave(group);
            }];

            dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{
                [self showLoading:NO];
                [self updateChartWithVibrationHistory:self.vibrationPoints temperatureSets:self.temperatureSets];
            });

Есть 2 входа и 2 выхода (на каждом из замыканий, возможно только быть успешным или неудачным, поэтому происходит только одно из 2)

Так почему мой код падает так? Как мне с этим справиться?

enter image description here

Единственное, что приходит на ум, это то, что несколько экземпляров этого объекта используются одновременно время. Возможно ли, что одна и та же группа используется этими разными экземплярами? Будет ли способ убедиться, что сама группа уникальна между этими экземплярами? Иначе я не могу понять, почему это происходит.

PS: я также добавил метку swift, чтобы привлечь больше внимания к вопросу, поскольку такая же проблема может возникнуть независимо от языка

РЕДАКТИРОВАТЬ 1

Добавление отсутствующих методов на основе полученных комментариев:

Это getTemperatureHistorySuccess, это тот, который потерпел крах

-(void)getTemperatureHistorySuccess:(void (^)(NSArray<TemperatureSetDTO*> *sets))success
                            failure:(void(^)(NSError *error))failure{
    NSMutableArray *sets = [NSMutableArray new];
    dispatch_group_t group = dispatch_group_create();

    for (TemperatureSummaryNew *sensor in self.regionPCA.temperatureSensors) {
        dispatch_group_enter(group);
        [TemperatureSensorsService getHistory:sensor.temperatureSensorID startDate:self.startDate stopDate:self.stopDate interval:self.currentInterval success:^(NSArray<TemperaturePointDTO *> *result) {
            TemperatureSetDTO *set = [TemperatureSetDTO new];
            set.points = result;
            [sets addObject:set];
            dispatch_group_leave(group);
        } failure:^(NSError *error) {
            dispatch_group_leave(group);
        }];
    }

    dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{
        success(sets);
    });
}

, а вот getHistory, который вызывается в l oop:

+ (void) getHistory:(int)sensorID
          startDate:(NSDate*)startDate
           stopDate:(NSDate*)stopDate
           interval:(HistoryInterval)interval
            success:(void (^)(NSArray<TemperaturePointDTO*>* result))success
            failure:(void(^)(NSError *error))failure{
    ApiManager *api = [ApiManager sharedManager];

    NSDictionary *params = @{
                             @"TemperatureSensorID" : [Converter toDictionaryValueFromInt:sensorID],
                             @"StartDate" : [Converter toDictionaryValueGMTFromDate:startDate],
                             @"StopDate" : [Converter toDictionaryValueGMTFromDate:stopDate],
                             @"Interval" : [Converter toDictionaryValueFromHistoryInterval:interval]};
    [api POST:kApiTemperatureSensorsGetHistory parameters:params progress:nil success:^(NSURLSessionDataTask *task, id responseObject) {
        if (success) {
            NSArray*  res = [Converter fromDictionaryValueToTemperaturePointDTOArray:responseObject];
            success(res);
        }
    } failure:^(NSURLSessionDataTask *task, NSError *error) {
        if (failure) {
            failure(error);
        }
    }];
}

Здесь getVibrationHistorySuccess

-(void)getVibrationHistorySuccess:(void (^)(NSArray<VibrationPointDTO *> *vibrationPoints))success
          failure:(void(^)(NSError *error))failure{
    __block NSArray<VibrationPointDTO *> *points;
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_enter(group);
    [self getDistanceHistorySuccess:^{
        dispatch_group_leave(group);
    } failure:^(NSError *error) {
        dispatch_group_leave(group);
    }];
    dispatch_group_enter(group);
    [VibrationSensorsService getHistory:self.regionPCA.regionID startDate:self.startDate stopDate:self.stopDate interval:self.currentInterval success:^(NSArray<VibrationPointDTO *> *result) {
        points = result;
        dispatch_group_leave(group);
    } failure:^(NSError *error) {
        dispatch_group_leave(group);
        failure(error);
    }];
    dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{
        success(points);
    });
}

VibrationSensorsService getHistory точно такой же, как предыдущий, но указывает на другую конечную точку

1 Ответ

1 голос
/ 13 января 2020

Вот последняя часть getVibrationHistorySuccess:failure:, скопированная с вашего вопроса:

[VibrationSensorsService getHistory:self.regionPCA.regionID startDate:self.startDate stopDate:self.stopDate interval:self.currentInterval success:^(NSArray<VibrationPointDTO *> *result) {
    points = result;
    dispatch_group_leave(group);
} failure:^(NSError *error) {
    dispatch_group_leave(group);
    failure(error);
}];
dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{
    success(points);
});

Этот код всегда вызывает success(points). Кроме того, иногда звонит failure(error). Это означает, что могут выполняться оба блока success и failure.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...