Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to break block loop in Objective - C?

I have these declarations in header file:
Note: I won't explain the whole code, I think it is easy to understand

typedef void (^loopCell)(id cell);
-(id)allCells:(loopCell)cell;

And allCells function implementation:

-(id)allCells:(loopCell)cell
{
    for (AAFormSection *section in listSections)
    {
        for (id _cell in section.fields) {
            cell(_cell);
        }
    }
    return nil;
}

The usage of allCells function:

-(void)setFieldValue:(NSString *)value withID:(int)rowID
{    
    [self allCells:^(id cell) {
        if([cell isKindOfClass:[AAFormField class]]) {
            AAFormField *_cell = (AAFormField *)cell;
            if(_cell.rowID == rowID) {
                _cell.value = value;
                //return; Here I want to terminate loop
            }
        }
    }];
}

My problem is, I can't terminate allCells loop in the middle (actually when I found object I need in the loop, I don't want iterate through other objects)

How can I stop allCells loop in the middle?

like image 849
Almas Adilbek Avatar asked Dec 27 '22 15:12

Almas Adilbek


2 Answers

Look at the docs for NSArray enumerateObjectsUsingBlock:. They setup the block signature to take a BOOL pointer. Set the stop BOOL to YES to cause the iteration to stop.

typedef void (^loopCell)(id cell, BOOL *stop);

-(id)allCells:(loopCell)cell {
    BOOL stop = NO;
    for (AAFormSection *section in listSections) {
        for (id _cell in section.fields) {
            cell(_cell, &stop);
            if (stop) {
                break;
            }
        }
        if (stop) {
            break;
        }
    }

    return nil;
}

-(void)setFieldValue:(NSString *)value withID:(int)rowID {    
    [self allCells:^(id cell, BOOL *stop) {
        if([cell isKindOfClass:[AAFormField class]]) {
            AAFormField *_cell = (AAFormField *)cell;
            if(_cell.rowID == rowID) {
                _cell.value = value;
                if (stop) {
                    *stop = YES;
                }
            }
        }
    }];
}
like image 128
rmaddy Avatar answered Jan 09 '23 04:01

rmaddy


You can't break from setFieldValue, but you can from allCells.

It's up to the method you're using that calls the block — allCells in this case — to provide a mechanism for stopping the loop. Usually, it's a parameter to the block.

If allCells is yours and you don't mind modifying it, you modify the block signature to take a pointer to a BOOL, initialized to YES, and check if the block modified it to NO.

(Note: You can break from a for in loop.)

like image 20
Steven Fisher Avatar answered Jan 09 '23 03:01

Steven Fisher