具有Xcode代码完成的Objective-C Block属性

And*_*rew 31 xcode objective-c ios objective-c-blocks xcode4

是否可以定义Objective-C块属性但在Xcode 4中仍然具有完整代码完成?

如果我使用typedef来定义块:

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

然后定义属性:

@property (nonatomic, copy) CompletionBlock completionBlock;

然后@synthesize在调用setter时我没有得到完整代码完成的属性.Xcode将使用typedef,因此,代码完成不使用完整块语法完成块参数,它使用typedef.

如果我在标头中定义了一个使用完整块语法而不是typedef的方法原型:

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

然后我使用@synthesize,提供的setter接近使用完整的代码完成语法,但关键是它省略了参数名称:

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

最后,如果我尝试@synthesize然后覆盖setter实现或将原型放在头文件中:

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

会出现一条警告,指出属性类型与访问者类型不匹配.无论我如何尝试使用语法,我都无法定义块属性和具有完整代码完成语法的setter.我可以吃蛋糕吗?

谢谢!

Mat*_*att 36

如果你愿意为你的类界面添加一行额外的代码,你绝对可以吃蛋糕并吃掉它.

首先,使用typedef定义块并像创建问题一样创建属性:

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

...

@property (nonatomic, copy) CompletionBlock completionBlock;
Run Code Online (Sandbox Code Playgroud)

接下来,正如MobileOverload在他的回答中指出的那样,我们知道如果在独立的方法声明中使用,Xcode为typedef'd块提供了正确的代码完成.所以,让我们为setter添加一个明确的声明completionBlock:

- (void)setCompletionBlock:(CompletionBlock)completionBlock;
Run Code Online (Sandbox Code Playgroud)

调用时,此方法解析为属性声明的setter方法.但是,因为我们在类接口中明确定义了它,所以Xcode会看到它并应用完整的代码完成.

因此,如果您包含所有这三行,您应该得到所需的结果.这种行为显然是Xcode的一个缺点,因为没有理由为什么@property语句中定义的setter 应该具有与自己定义的相同方法不同的代码完成.

  • 这很有效,谢谢!我将为此提交一份错误报告,希望将来我们不需要明确的方法声明. (2认同)