4

我有一个块存储为类中的实例变量

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

我希望 xcode 自动填充块,就像您键入 [UIView animateWithDuration 和 xcode 自动完成块时一样。

当我自动完成我的块时,它只会填写

[self.suggestedSearchTermView setWordSelected:(didSelectWord)wordSelected

代替

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

是否可以更改某些内容以使 Xcode 了解如何自动完成此块?

4

3 回答 3

10

好的,我做了一些测试。

显然你有两个(远非完美)选择:

  1. 避免typedef并将属性声明为

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

    如评论中所述,这具有在自动完成中跳过参数名称的缺点。

  2. 在接口中显式添加 setter 声明

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

    这将导致 Xcode 在 setter 定义之前解析类型定义,从而为您提供您所期望的漂亮的自动完成功能。明显的缺点是接口中的额外设置器声明。

也就是说,您应该填写错误报告: http: //openradar.appspot.com/

于 2013-08-28T11:28:06.603 回答
2

在没有 的情况下声明您的财产typedef,如下所示:

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

有了这个定义,Xcode 会给你下面的扩展:

MyClass *test = [MyClass new];
[test setWordSelected:(void (^)(NSString *))wordSelected];
于 2013-08-28T11:15:26.823 回答
1

在更加沮丧的情况下,我做了一个宏观巩固这个粗略的过程..

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

现在以前需要什么(正确的自动完成)..

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

简直就是

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

相当简单,不那么冗长,并且您可以获得 typedef AND 的好处,并且您不必创建难看的、理论上不需要的 setter 声明!

如果你想重用一个“类型”,你需要另一个(这一次只需要三个参数(因为块类型不能重新声明)。

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

BlockProp(OnEvent,anotherVar,AnotherVar);

即使它们的签名匹配(使用第一个宏),您也可以为每个属性创建一个新的块类型(名称),但这有点恶心。享受!

于 2014-09-30T05:20:39.577 回答