简体   繁体   中英

Objective-C Block Property with Xcode code completion

Is it possible to define an Objective-C block property but still have full-code completion in Xcode 4?

If I use a typedef to define the block:

typedef void (^CompletionBlock)(MyObject *myObj);

and then define the property:

@property (nonatomic, copy) CompletionBlock completionBlock;

and then @synthesize the property I don't get full code completion when calling the setter. Xcode will use the typedef and because of this, the code completion doesn't use the full block syntax complete with block parameters, it uses the typedef.

If I define a method prototype in the header that uses the full block syntax instead of the typedef:

@property (nonatomic, copy) void (^completionBlock)(MyObject *myObj);

and then I use @synthesize , the provided setter comes close to using the full code completion syntax but crucially it leaves out the parameter names:

[self setCompletionBlock:(void (^)(MyObject *)) { ... }

Finally, if I try to @synthesize and then override the setter implementation or put the prototype in the header:

- (void)setCompletionBlock:(void (^)(MyObject *myObj))completionBlock {...}

A warning is raised stating that the property type does not match the accessor type. No matter how I try to finagle the syntax, I'm not able to both define a block property and a setter that has the full syntax for code completion. Can I have my cake and eat it too?

Thanks!

You can definitely have your cake and eat it too, if you are willing to add one extra line of code to your class interface.

First, define block with a typedef and create a property like you did in your question:

typedef void (^CompletionBlock)(MyObject *myObj);

...

@property (nonatomic, copy) CompletionBlock completionBlock;

Next, as MobileOverload pointed out in his answer, we know that Xcode provides correct code completion for typedef'd blocks if used in a standalone method declaration. So, let's add an explicit declaration for the setter of completionBlock :

- (void)setCompletionBlock:(CompletionBlock)completionBlock;

When called, this method resolves to the setter method declared by the property. However, because we explicitly defined it in the class interface, Xcode sees it and applies full code completion.

So, if you include all three of those lines you should get the desired result. This behavior is clearly a shortcoming of Xcode, as there is no reason why a setter defined in a @property statement should have different code completion than the same method defined on its own.

You can get some fancy looking code completion when passing your blocks as an argument to a method in your class. In the header file I typedef'd the block like this

typedef void (^MyCompletionBlock)(id obj1, id obj2);

Then I was able to use it as an argument to my method that I have also declared in this class header.

-(void)doThisWithBlock:(MyCompletionBlock)block;

In the m file I declared the method

-(void)doThisWithBlock:(MyCompletionBlock)block {
    NSLog(@"Something");
}

and when I went to call it I got fancy code completion like this. CodeCompletion1

CodeCompletion2

Hopefully this answers your question.

Ok so I figured out a stopgap way of doing this that does't result in warnings / errors... and actually makes things easier to read / shorter to type, etc.

define a macro with our "abbreviation", and then use the full format in the property declaration like...

#define TINP NSString*(^)(NSString *typed, const char *raw)
@interface ....
@property (copy) NSString*(^termDidReadString)(NSString *typed, const char *raw);

subsequently.. you can then reference that "kind" of argument, etc like..

+ (void)addInputBlock:(TINP)termDidReadString;

and voilá... not only will your code be TINIER!! but code completion will work, like a charm...

在此输入图像描述

I dont know about full code completions but you can use code snippets to get code completion like behavior and you can use place holders in code snippets <#PLACE HOLDER#> . Hope this will help you

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