Как написать лямбда-методы в Objective-C?

Как написать лямбда-методы в Objective-C?

Ответ 1

Концепция лямбда в Objective-C теперь инкапсулирована идеей Blocks, которая являются эквивалентом функций сквозной ссылки. Конечно, возможно, у кого-то было уже с C с идеей указателей функций; блоки - это просто способ захвата локального состояния (т.е. может быть замыканием). Фактически, блоки также могут использоваться и на других языках C (на Mac) - есть предложение сделать их частью стандартного синтаксиса C.

Здесь пример определения lambda для умножения двух чисел:

int (^mult)(int, int) = ^(int a, int b) { return a*b; };

Первая часть объявляет переменную типа ^int(int,int), а затем присваивает ее выражению лямбда (aka block), которое возвращает кратное его двух аргументов. Затем вы можете передать это fn вокруг, определить его в других местах и ​​т.д.; вы можете даже использовать его в других функциях.

Здесь пример определения функции, которая при вызове возвращает другую функцию:

multiplyBy = ^(int a) { return ^(int b) { return b*a; }; };
triple = multiplyBy(3);

Обратите внимание, что вы можете смешивать блоки с типами объектов (обычно используя id в качестве типа объекта), и многие из новых структур данных объекта Objective-C имеют некоторую операцию на блочном уровне. GCD также использует блоки для прохождения в произвольных событиях; однако обратите внимание, что GCD также можно использовать с указателями функций.

Ответ 2

OS X 10.6 введены блоки. См. ответ AlBlue для примеров.

Если вы не используете Snow Leopard, вы можете получить что-то близкое к композиции функций, используя различные другие функции.

Пример использования указателей функций C:

void sayHello() {
    NSLog(@"Hello!");
}

void doSomethingTwice(void (*something)(void)) {
    something();
    something();
}

int main(void) {
    doSomethingTwice(sayHello);
    return 0;
}

Пример использования шаблона команды:

@protocol Command <NSObject>
- (void) doSomething;
@end

@interface SayHello : NSObject <Command> {
}
@end

@implementation SayHello
- (void) doSomething {
    NSLog(@"Hello!");    
}
@end

void doSomethingTwice(id<Command> command) {
    [command doSomething];
    [command doSomething];
}

int main(void) {
    SayHello* sayHello = [[SayHello alloc] init];
    doSomethingTwice(sayHello);
    [sayHello release];
    return 0;
}

Пример использования селектора:

@interface SaySomething : NSObject {
}
- (void) sayHello;
@end

@implementation SaySomething
- (void) sayHello {
    NSLog(@"Hello!");    
}
@end

void doSomethingTwice(id<NSObject> obj, SEL selector) {
    [obj performSelector:selector];
    [obj performSelector:selector];
}

int main(void) {
    SaySomething* saySomething = [[SaySomething alloc] init];
    doSomethingTwice(saySomething, @selector(sayHello));
    [saySomething release];
    return 0;
}

Ответ 3

Я слышал, как Андре Панг в NSConference рассказывал о том, как будут собираться блоки со следующей версией Objective-C.

Это должно позволить функциональное программирование.

Изменить: поскольку Snow Leopard выпущен, это действительно так. Objective-C теперь имеет Blocks.