An array of blocks?

It seems to me that this is a very strange interaction, but at the same time it not only works, but also does not cause any warnings or errors in this process. I just want to better understand the block as a whole and why something like this might be right or wrong.

Is there a reason why something like this should not be done?

NSArray *array = [NSArray arrayWithObjects:^{NSLog(@"Block 1");}, ^{NSLog(@"Block 2");}, ^{NSLog(@"Block 3");}, nil]; for (id block in array) { [block invoke]; } 
+4
source share
3 answers

Putting blocks into NSArray ; these are objects. In fact, they inherit from NSObject .

However, you need to copy them. These blocks are created on the stack and need to be moved to the heap to get past the end of the current method. If you use ARC, this is easy:

 NSArray *array = [NSArray arrayWithObjects:[^{NSLog(@"Block 1");} copy], ... 

In MRR, you need to balance this copy value, so you have two unpleasant options: use temps or list the array immediately after creating it and send release all your members.

Submitting invoke , on the other hand, is not completely kosher because it is a private method. The only fully API compatible way to call a block is the syntax of the call function:

 typedef GenericBlock dispatch_block_t; for( GenericBlock block in array ){ block(); } 
+3
source

Of course, that’s good. Why won't it be good?

In languages ​​like JavaScript, this method is common when registering event handlers.

 object.clickHandlers.push(function() { doStuff() }); object.clickHandlers.push(function() { doMoreStuff() }); 

I see no reason why such methods could not be used with ObjC blocks, since they are real objects.

A more interesting question, however, is that this template is the best choice for any purpose. What you didn’t really tell us.

+1
source

Blocks in Objective-C are first-class citizen objects. Regardless of what you can do for a regular object, whether it be passing as a parameter, storing in an array or dictionary, etc., you can do this to lock objects.

For example, an array of block objects may be useful for encoding a sequence of actions that is unknown at compile time; a dictionary of block objects supported by strings can be useful in implementing a scripting language, etc.

The best way to call a block retrieved from a collection is to assign it to the correct type and use the regular block call syntax on it.

+1
source

All Articles