Search code examples
iosobjective-cios5booleanobjective-c-blocks

BOOL method not returning YES inside of block


I have created a new method which returns a BOOL, shown below.

+(BOOL)checkIfGameAlreadyExistsAgainst:(PFUser *)opponentUser {
    // Find all the games where the current user is user1 and the opponentUser is user2
    PFQuery *currentUserIsUser1 = [PFQuery queryWithClassName:@"Game"];
    [currentUserIsUser1 whereKey:kMESGameUser1 equalTo:[PFUser currentUser]];
    [currentUserIsUser1 whereKey:kMESGameUser2 equalTo:opponentUser];
    [currentUserIsUser1 whereKey:kMESGameIsActive equalTo:[NSNumber numberWithBool:YES]];
    [currentUserIsUser1 findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        if (objects) {
            // We have games where the current user is user1
            // NEED TO RETURN NO TO THIS METHOD AND NOT RUN FURTHER IN METHOD...
            NSLog(@"Results returned for existing game where current user is User1. Results: %@",objects);
        } else {
            // If there are no objects from first query and no error we run the second query
            if (!error) {
                // Find all the games where the current user is user2 and the opponentUser is user1
                PFQuery *currentUserIsUser2 = [PFQuery queryWithClassName:@"Game"];
                [currentUserIsUser2 whereKey:kMESGameUser1 equalTo:opponentUser];
                [currentUserIsUser2 whereKey:kMESGameUser2 equalTo:[PFUser currentUser]];
                [currentUserIsUser2 whereKey:kMESGameIsActive equalTo:[NSNumber numberWithBool:YES]];
                [currentUserIsUser2 findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
                    if (objects) {
                        // We have games where the current user is user2
                        // NEED TO RETURN NO TO THIS METHOD AND NOT RUN FURTHER IN METHOD...
                        NSLog(@"Results returned for existing game where current user is User2. Results: %@",objects);
                    }
                }];
            }
        }
    }];


    return NO;
}

The problem I have is how to return a YES value within a block within the method. See the sections in the method which say // NEED TO RETURN NO TO THIS METHOD AND NOT RUN FURTHER IN METHOD... How can I return YES here. If I add return YES I get an incompatible pointer types error.

Further to this, once I have the method returning YES, how do I call this method and do something depending on the result. For example I need to call this method and if it is true then do something else, if not do nothing...


Solution

  • I am not sure what you are asking, so here is a guess: you wish your block to return a value to checkIfGameAlreadyExistsAgainst.

    When a block in constructed it usually makes a copy of any value referenced from its environment. If you wish your block to modify a variable in its environment you must mark that variable with __block. In your code this would look something like:

    __block BOOL blockStatus = YES;
    [currentUserIsUser1 findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error)
     {
        ...
        blockStatus = NO;
     }
    ];
    
    if (!blockStatus)
    {
       ...
    }
    

    Important: The name of the method you are calling, findObjectsInBackgroundWithBlock, suggests that the block may not be called synchronously, which means the call may return before the block is executed. If this is the case you need to tackle the issue in a different way; which may involve calling a synchronous equivalent of findObjectsInBackgroundWithBlock or modifying checkIfGameAlreadyExistsAgainst so that it accepts a block which it calls asynchronously with its result rather than returning a value directly.

    HTH