1

Get confused a bit with a question of how to pass the block to the method but without the defined (concrete) params.

like that:

 - (void)someMethodWithBlockAsParam:(generic block)block 

is it possible at all regarding to Obj-C

Seems like I saw this trick somewhere but can't remember where.

Thank in advance.

David
  • 1,061
  • 11
  • 18
  • 1
    Could you pass pointer-to-void and cast? See. e.g. http://stackoverflow.com/questions/11106224/how-to-cast-blocks-to-and-from-void – matt Dec 24 '15 at 03:31
  • @matt - surely casting a pointer to an object, the block, to a void pointer is not the best choice in an ARC world... – CRD Dec 24 '15 at 20:35
  • @CRD I don't see what it has to do with ARC. The answer to question I linked to shows you how to handle the memory management. Pointer-to-void _is_ the generic type in C/Objective-C; there are lots of situations where we pass an object pointer cast as pointer-to-void. – matt Dec 24 '15 at 22:39
  • @matt - surely `id` is the generic *object* type in Objective-C, and if that type is used in conjunction with ARC there is no need to handle the memory management in a situation like this - it is handled automatically. Now I'm at a Mac I've added an answer showing this. Why `bridge` when you don't need to? Or maybe I'm missing something... – CRD Dec 25 '15 at 05:05
  • @CRD I like your idea, actually; this was a good discussion. – matt Dec 25 '15 at 18:38

3 Answers3

3

You need to declare something, otherwise the callsite for that block won't know what to pass in or what to expect in return. In particular, it needs to know whether they are going to be Objective C objects or not, because otherwise it can't refcount them correctly.

If you just want a block that takes no arguments and returns nothing (a callback, basically) then you can use dispatch_block_t:

- (void)someMethodWithBlockAsParam:(dispatch_block_t)block 
Avi
  • 7,469
  • 2
  • 21
  • 22
Ewan Mellor
  • 6,747
  • 1
  • 24
  • 39
  • Perhaps he wants to be able to pass a generic block, and on the receiving end cast it to a specific signature before actually calling it (Like you would do with variables and `void*`). Not sure if that's possible, though. – Nicolas Miari Dec 24 '15 at 04:01
  • 1
    Umm, if you want a block like that, you use `dispatch_block_t`. That's what it's there for. – Avi Dec 24 '15 at 05:55
2

Get confused a bit with a question of how to pass the block to the method but without the defined (concrete) params.

It's not clear to me exactly what you are asking here, but it sounds like you wish to be able to pass any block to a method which presumably at some later point you cast to a specific block type so you can call it. If so:

A block in modern (post late 2014 - see this question and answer for why that date) ARC Objective-C is a fully automatically managed object. Therefore the standard "any object" type id may be used to pass any block.

For example given:

// a specific block type
typedef id (^SelectBlock)(NSArray *, NSUInteger);

// method which takes a general object and casts to a specific block type
- (void) useBlock:(id)blockObj
{
   SelectBlock sb = (SelectBlock)blockObj;
   id item = sb(@[@"apple", @"pear", @"plum"], 2);
   NSLog(@"Result: %@", item);

}

// method which pass a block as "any object"
- (void) test:(NSUInteger)offset
{
   SelectBlock mySelect = ^(NSArray *collection, NSUInteger index)
                          {
                             return collection[index-offset];
                          };
   [self useBlock:(id)mySelect];
}

then the call:

[self test:1];

will result in pear being output.

Passing a block "generically" in this way is only useful if the original type is somehow known so the id typed valued can be cast back to the correct block type to invoke the block.

Community
  • 1
  • 1
CRD
  • 52,522
  • 5
  • 70
  • 86
  • Good answer. Of course, if the passed block does not conform to the signature it is cast to, calling it will trigger a runtime error, right? – Nicolas Miari Dec 25 '15 at 05:14
  • @NicolasMiari - absolutely! This is the standard problem when you cast away type information and is not specific to blocks, if you cast back to the wrong type bad things can happen. Hence the comment in the last paragraph. – CRD Dec 25 '15 at 05:25
0

How about you define a block with one NSDictionary parameter where you can place any number and any kinds of objects as the parameters?

typedef void (^aBlock)(NSDictionary* parameters);
Ahmed Hamed
  • 504
  • 1
  • 3
  • 11