Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xcode omitting parameters names of block

I have a block property that looks like this:

@property (nonatomic, copy) void (^indexChangeBlock)(NSInteger index);

When I try to set the value for this property, Xcode autocomplete will omit the parameter name leaving me with something like this:

[self.segmentedControl3 setIndexChangeBlock:^(NSInteger) {
    code
}];

Then Xcode shows a Parameter name omitted error. I'm aware that I can solve this by adding the parameter name manually to make it look like this:

[self.segmentedControl3 setIndexChangeBlock:^(NSInteger index) {
    code
}];

My questions is, how can I make Xcode add the parameters names automatically. Or in other words, prevent it from removing them.

like image 583
Hesham Avatar asked Jan 21 '13 14:01

Hesham


2 Answers

possible solution:

typedef void (^IndexChangeBlock)(NSInteger index);

and define your property with

@property (nonatomic, copy) IndexChangeBlock indexChangeBlock;

and if you add

- (void)setIndexChangeBlock:(IndexChangeBlock)indexChangeBlock;

everything should work

like image 126
Jonathan Cichon Avatar answered Oct 14 '22 01:10

Jonathan Cichon


In exacerbated frustration, I made a macro consolidating this gross process..

#define BlockProperty(SIGNATURE,TYPENAME,varname,Varname) typedef SIGNATURE; @property (nonatomic,copy) TYPENAME varname; - (void) set##Varname:(TYPENAME)_

Now what Previously would've required (for proper autocompletion)..

typedef void(^OnEvent)(BOOL ok,id result);
@property (nonatomic,copy) OnEvent varname;
- (void) setVarname:(OnEvent)_;

is simply

BlockProperty(void(^OnEvent)(BOOL ok, id result),OnEvent,varname,VarName);

QUITE a bit easier, less verbose, AND you get the benefit of the typedef AND and you don't have to create the unsightly, theoretically unneeded setter declaration!

If you WANT to reuse a "type" you'll need another one (which this time will only take THREE parameters (as the block type cannot be redeclared).

#define BlockProp(TYPENAME,varname,Varname) @property (nonatomic,copy) TYPENAME varname; - (void)  set##Varname:(TYPENAME)_

BlockProp(OnEvent,anotherVar,AnotherVar);

You could just create a new block type (name) for each property even if their signatures match (using the first macro), but that's kind of gross. Enjoy!

like image 28
Alex Gray Avatar answered Oct 14 '22 01:10

Alex Gray