Xcode пропуска имена на параметри на блок

Имам свойство на блок, което изглежда така:

@property (nonatomic, copy) void (^indexChangeBlock)(NSInteger index);

Когато се опитам да задам стойността за това свойство, Xcode autocomplete ще пропусне името на параметъра, оставяйки ми нещо подобно:

[self.segmentedControl3 setIndexChangeBlock:^(NSInteger) {
    code
}];

Тогава Xcode показва грешка Parameter name omitted. Наясно съм, че мога да разреша това, като добавя ръчно името на параметъра, за да изглежда така:

[self.segmentedControl3 setIndexChangeBlock:^(NSInteger index) {
    code
}];

Въпросът ми е как мога да накарам Xcode автоматично да добавя имената на параметрите. Или с други думи, попречете му да ги премахне.


person Hesham    schedule 21.01.2013    source източник
comment
Но типът на indexChangeBlock е просто void (^)(NSInteger). Няма име на параметър в тип функция или тип блок. Безсмислено е за езика.   -  person newacct    schedule 22.01.2013
comment
Да, това е безсмислено за езика, но е полезно за автоматично довършване в Xcode, особено когато вашият код ще се използва от други.   -  person Hesham    schedule 22.01.2013
comment
FWIW, току-що тествах горния синтаксис в Xcode 12.5.1 и автоматичното попълване вече включва името на параметъра.   -  person Rob    schedule 26.06.2021
comment
Радвам се да знам, че е поправено 8 години по-късно.   -  person Hesham    schedule 30.06.2021


Отговори (2)


възможно решение:

typedef void (^IndexChangeBlock)(NSInteger index);

и дефинирайте собствеността си с

@property (nonatomic, copy) IndexChangeBlock indexChangeBlock;

и ако добавите

- (void)setIndexChangeBlock:(IndexChangeBlock)indexChangeBlock;

всичко трябва да работи

person Jonathan Cichon    schedule 21.01.2013
comment
Xcode ще го допълни автоматично до [self.segmentedControl3 setIndexChangeBlock:(IndexChangeBlock)indexChangeBlock], така че е още по-досадно. - person Hesham; 21.01.2013
comment
редактирах моя отговор, за съжаление трябва да добавите ръчно декларацията за настройка - person Jonathan Cichon; 21.01.2013
comment
Сега работи като чар, благодаря! Също така си струва да споменем, че може да работи и без typedef. Само свойството и методът за настройка - (void)setIndexChangeBlock:(void (^)(NSInteger index))indexChangeBlock; ще свършат работа. - person Hesham; 22.01.2013

В изострено разочарование направих макрос, който консолидира този груб процес.

#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 и не е нужно да създавате грозната, теоретично ненужна декларация за настройка!

Ако ИСКАТЕ да използвате повторно „тип“, ще ви е необходим друг (който този път ще приеме само ТРИ параметъра (тъй като типът блок не може да бъде предеклариран).

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

BlockProp(OnEvent,anotherVar,AnotherVar);

Можете просто да създадете нов тип блок (име) за всяко свойство, дори ако техните подписи съвпадат (с помощта на първия макрос), но това е някак грубо. Наслади се!

person Alex Gray    schedule 30.09.2014