Search code examples
objective-cblockdispatch-async

Waiting for code to execute (already used dispatch groups)


Got this lengthy section of code shown below and I've hit a brick wall. Basically the code runs perfectly and does exactly what I want it to do. However, it needs to finish running all the code within this section before printing the "Finished" at the end. However adding semaphores or another dispatch group forces a breakpoint. Might be obvious, but could someone give me a bit of advice on this please?

Note: I cannot use that dispatch at the bottom to call another method. Remember its within a loop.

for (id i in arr) {
    searchByName = nil;
    if ([i containsString:@"word1"] || [i containsString:@"word2"]) {
        NSRange searchFromRange = [i rangeOfString:@"ong>"];
        NSRange searchToRange = [i rangeOfString:@"</str"];
        NSString *substring = [i substringWithRange:NSMakeRange(searchFromRange.location+searchFromRange.length, searchToRange.location-searchFromRange.location-searchFromRange.length)];
        [allergens addObject:substring];
        if ([substring isEqualToString:@"Examee"] && veg_lac_ovoSafe == TRUE) {
            veg_ovoSafe = FALSE;
            vegSafe = FALSE;
        }
        else if ([substring isEqualToString:@"Example"] && veg_lac_ovoSafe == TRUE) { //USE OF HEURISTICS
            veg_lacSafe = FALSE;
            vegSafe = FALSE;
        }
        else if ([substring isEqualToString:@"Exam"]) {
            pescetarianSafe = TRUE;
            vegSafe = FALSE;
            veg_ovoSafe = FALSE;
            veg_lacSafe = FALSE;
            veg_lac_ovoSafe = FALSE;
            pollotarianSafe = FALSE;
        }
        NSCharacterSet *charactersToRemove = [[NSCharacterSet alphanumericCharacterSet] invertedSet];
        NSCharacterSet *numbersToRemove = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
        substring = [[substring componentsSeparatedByCharactersInSet:charactersToRemove] componentsJoinedByString:@""];
        searchByName = [[[substring componentsSeparatedByCharactersInSet:numbersToRemove] componentsJoinedByString:@""] lowercaseString];
    }
    else {
        NSCharacterSet *charactersToRemove = [[NSCharacterSet alphanumericCharacterSet] invertedSet];
        NSCharacterSet *numbersToRemove = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
        NSString *searchItem = [[i componentsSeparatedByCharactersInSet:charactersToRemove] componentsJoinedByString:@""];
        searchByName = [[[searchItem componentsSeparatedByCharactersInSet:numbersToRemove] componentsJoinedByString:@""] lowercaseString];
    }
    if (![searchByName isEqualToString:@" "]) {
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
        dispatch_group_enter(_groupSearch);
        dispatch_async(queue, ^{
            [[self databaseQuery:searchByName] observeEventType:FIRDataEventTypeChildAdded
                                                      withBlock:^(FIRDataSnapshot * _Nonnull snapshot) {
                if (snapshot.value != NULL) {
                    NSLog(@"%@", snapshot.value);
                    for (int i=0; i < [[NSString stringWithFormat:@"%@", snapshot.value] length]; i++) {
                        NSString *x  = [NSString stringWithFormat:@"%c", [[NSString stringWithFormat:@"%@", snapshot.value] characterAtIndex:i]];
                        NSLog(@"%@", x);
                        if ([x isEqualToString:@"1"]) {
                            vegSafe = FALSE;
                        }
                        else if ([x isEqualToString:@"2"]) {
                            vegSafe = FALSE;
                            veg_lacSafe = FALSE;
                        }
                        else if ([x isEqualToString:@"3"]) {
                            vegSafe = FALSE;
                            veg_ovoSafe = FALSE;
                        }
                        else if ([x isEqualToString:@"4"]) { //Could use switch case.
                            vegSafe = FALSE;
                            veg_lac_ovoSafe = FALSE;
                            veg_lacSafe = FALSE;
                            veg_ovoSafe = FALSE;
                        }
                        else if ([x isEqualToString:@"5"]) {
                            pescetarianSafe = FALSE;
                        }
                        else if ([x isEqualToString:@"6"]) {
                            pollotarianSafe = FALSE;
                        }
                    }
                }

                dispatch_group_leave(_groupSearch);
            }
                                                withCancelBlock:^(NSError * _Nonnull error) {
                NSLog(@"%@", error.localizedDescription);
                dispatch_group_leave(_groupSearch);
            }];
        });
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            dispatch_group_wait(_groupSearch, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)));
            dispatch_sync(queue, ^{
                //Hi
            });
        });
    }
}

NSLog(@"Finished");

Solution

  • Your use of dispatch_group_wait is in the wrong place. It needs to after the for loop, not inside it. And you can create queue before the loop and reuse it as needed.

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
    
    for (id i in arr) {
        searchByName = nil;
    
        // Lots of other code here
    
        if (![searchByName isEqualToString:@" "]) {
            dispatch_group_enter(_groupSearch);
            dispatch_async(queue, ^{
                [[self databaseQuery:searchByName] observeEventType:FIRDataEventTypeChildAdded withBlock:^(FIRDataSnapshot * _Nonnull snapshot) {
                    if (snapshot.value != NULL) {
                        NSLog(@"%@", snapshot.value);
                        for (int i=0; i < [[NSString stringWithFormat:@"%@", snapshot.value] length]; i++) {
                            NSString *x  = [NSString stringWithFormat:@"%c", [[NSString stringWithFormat:@"%@", snapshot.value] characterAtIndex:i]];
                            NSLog(@"%@", x);
                            if ([x isEqualToString:@"1"]) {
                                vegSafe = FALSE;
                            }
                            else if ([x isEqualToString:@"2"]) {
                                vegSafe = FALSE;
                                veg_lacSafe = FALSE;
                            }
                            else if ([x isEqualToString:@"3"]) {
                                vegSafe = FALSE;
                                veg_ovoSafe = FALSE;
    
                            }
                            else if ([x isEqualToString:@"4"]) { //Could use switch case.
                                vegSafe = FALSE;
                                veg_lac_ovoSafe = FALSE;
                                veg_lacSafe = FALSE;
                                veg_ovoSafe = FALSE;
                            }
                            else if ([x isEqualToString:@"5"]) {
                                pescetarianSafe = FALSE;
                            }
                            else if ([x isEqualToString:@"6"]) {
                                pollotarianSafe = FALSE;
                            }
                        }
                    }
                    dispatch_group_leave(_groupSearch);
                }
                withCancelBlock:^(NSError * _Nonnull error) {
                    NSLog(@"%@", error.localizedDescription);
                    dispatch_group_leave(_groupSearch);
                }];
    
            });
        }
    }
    
    dispatch_group_wait(_groupSearch, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)));
    
    NSLog(@"Finished");