简体   繁体   中英

How to get the correct autocomplete in XCode for a block variable?

I have a block thats stored as an instance variable in a class

typedef void ((^didSelectWord)(NSString* word));
@property (nonatomic,strong) didSelectWord wordSelected;

and i want xcode to auto fillout the block like when you type [UIView animateWithDuration and xcode autocompletes a block for it.

When i autocomplete my block it just fills out

[self.suggestedSearchTermView setWordSelected:(didSelectWord)wordSelected

instead of

[self.suggestedSearchTermView setWordSelected:^(NSString *word) {

Is it possible to change something to make Xcode understand how to autocomplete this block?

Ok I did some testing.

Apparently you have two (far from perfect) options:

  1. avoid the typedef and declare the property as

     @property (nonatomic,strong) void (^wordSelected)(NSString * word); 

    As noted in the comments, this has the drawback of skipping the parameter name in the autocompletion.

  2. explicitly add a setter declaration in the interface

     typedef void ((^DidSelectWordBlock)(NSString* word)); @interface YourClass : NSObject @property (nonatomic,strong) DidSelectWordBlock wordSelected; - (void)setWordSelected:(DidSelectWordBlock)wordSelected; @end 

    this will cause Xcode to resolve the type definition before the setter definition, giving you the nice autocompletion that you would expect. The obvious drawback is the extra setter declaration in the interface.

That said, you should fill in a bug report: http://openradar.appspot.com/

Declare your property without typedef , like this:

@property (nonatomic,strong) void (^wordSelected)(NSString *word);

With this definition Xcode would give you the expansion below:

MyClass *test = [MyClass new];
[test setWordSelected:(void (^)(NSString *))wordSelected];

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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM