Подтвердить что ты не робот

Objective-C Свойство Block с завершением кода Xcode

Можно ли определить свойство блока 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, предоставленный наборщик близок к использованию полного синтаксиса завершения кода, но, в решающей степени, он не содержит имен параметров:

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

Наконец, если я попытаюсь @synthesize, а затем переопределить реализацию сеттера или поместить прототип в заголовок:

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

Выдается предупреждение о том, что тип свойства не соответствует типу доступа. Независимо от того, как я пытаюсь настроить синтаксис, я не могу определить свойство блока и сеттер, который имеет полный синтаксис для завершения кода. Могу ли я получить торт и съесть его?

Спасибо!

4b9b3361

Ответ 1

Вы можете наверняка иметь свой торт и съесть его, если вы хотите добавить одну дополнительную строку кода в свой интерфейс класса.

Сначала определите блок с помощью typedef и создайте свойство, как в вашем вопросе:

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

...

@property (nonatomic, copy) CompletionBlock completionBlock;

Далее, как отметил MobileOverload в своем ответе, мы знаем, что Xcode обеспечивает правильное завершение кода для блоков typedef'd, если они используются в объявлении автономного метода. Итак, добавьте явное объявление для установщика completionBlock:

- (void)setCompletionBlock:(CompletionBlock)completionBlock;

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

Итак, если вы включите все три из этих строк, вы получите желаемый результат. Такое поведение явно является недостатком Xcode, так как нет причин, по которым установщик, определенный в операторе @property, должен иметь другое завершение кода, чем тот же самый метод, определенный самостоятельно.

Ответ 2

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

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

Затем я смог использовать его в качестве аргумента для моего метода, который также был объявлен в этом заголовке класса.

-(void)doThisWithBlock:(MyCompletionBlock)block;

В файле m я объявил метод

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

и когда я пошел называть его, я получил причудливое завершение кода, как это. CodeCompletion1

CodeCompletion2

Надеюсь, это ответит на ваш вопрос.

Ответ 3

Хорошо, поэтому я выяснил, как это сделать, что не приводит к предупреждениям/ошибкам... и на самом деле упрощает чтение/сокращение типов и т.д.

определить макрос с нашей "аббревиатурой", а затем использовать полный формат в объявлении свойства, например...

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

впоследствии.. вы можете ссылаться на этот "вид" аргумента и т.д., как..

+ (void)addInputBlock:(TINP)termDidReadString;

и voilá... не только ваш код будет TINIER!! но завершение кода будет работать, как прелесть...

enter image description here

Ответ 4

Я не знаю о завершении полного кода, но вы можете использовать фрагменты кода, чтобы получить завершение кода, например поведение, и вы можете использовать держатели мест в фрагментах кода < #PLACE HOLDER # > . Надеюсь, это поможет вам.