2013-08-28 2 views
4

У меня есть блок Thats, хранящиеся в переменной экземпляра в классеКак получить правильный автозаполнение в XCode для переменной блока?

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

и я хочу Xcode для автоматического Fillout блока, как при вводе [UIView animateWithDuration и Xcode autocompletes блок для него.

Когда я автозаполнение мой блок, он просто заполняет

[self.suggestedSearchTermView setWordSelected:(didSelectWord)wordSelected 

вместо

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

Можно ли что-то изменить, чтобы сделать Xcode понять, как автозаполнение этот блок?

ответ

10

Хорошо я сделал некоторые испытания.

Видимо у вас есть два (далеко от совершенства) опции:

  1. избежать typedef и объявить свойство, как

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

    Как было отмечено в комментариях, это имеет тот недостаток, пропуская имя параметра в автозапуске.

  2. явно добавить объявление сеттера в интерфейсе

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

    это приведет к Xcode, чтобы разрешить определение типа перед определением сеттера, давая вам хорошее автозавершение, что можно было бы ожидать. Очевидным недостатком является дополнительное объявление сеттера в интерфейсе.

Тем не менее, вы должны заполнить сообщение об ошибке: http://openradar.appspot.com/

+0

Первый вариант дает self.suggestedSearchTermView setWordSelected:^(NSString *) { <#code#> } как завершение. Это почти, но теперь оно не заполняет имя переменной слова. Любое предложение? – hakonbogen

+1

Боюсь, что это ограничение. Сообщите об этом как об ошибке, и надейтесь на лучшее в Xcode 5. –

+0

Apple не обязательно смотрит на openradar. Ошибки должны быть отправлены по адресу http://bugreport.apple.com, а затем скопированы в openradar для видимости сообщества. – Jasarien

2

Объявите вашу собственность без typedef, как это:

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

С этим определением Xcode даст вам расширение ниже:

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

Обратите внимание, что он автоматически помещает 'int', потому что вы не указали тип возврата. –

+0

@dasblinkenlight объявление свойства дает мне ошибку компилятора: имя типа требует спецификатора или квалификатора – hakonbogen

+0

@Hakonbogen С помощью Gabriele Petronella это исправлено. – dasblinkenlight

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); 

СОВСЕМ немного легче, компактнее, и вы получите выгоду от ЬурейеГо И, и вы не должны создавать неэстетичное, теоретически ненужное заявление сеттера!

Если вы хотите повторно использовать «тип», вам понадобится еще один (который на этот раз будет принимать только три параметра (поскольку тип блока не может быть повторно разрешен).

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

BlockProp(OnEvent,anotherVar,AnotherVar); 

Вы можете просто создать новый тип блока (имя) для каждого свойства, даже если их подписи матч (с помощью первого макроса), но это своего рода брутто. Наслаждайтесь!

Смежные вопросы