Передать блок методу C++ из цели C

У меня есть вспомогательный класс С++, который я использую с Objective-C. Я хотел бы передать классу С++ блок из контроллера представления (обратный вызов), чтобы при его выполнении я находился в основном потоке и мог обновлять пользовательский интерфейс. В настоящее время у меня есть аналогичная система, работающая с указателями функций и performSelector при вызове функции. Мне нужен пример того, как настроить переменную С++ и как передать ей блок Objective-C и вызвать его из класса С++.

Если это невозможно, можете ли вы придумать другое/лучшее решение?


person Aran Mulholland    schedule 16.05.2011    source источник
comment
Что заставляет вас думать, что вы не можете просто передать блок в качестве параметра одному из методов объекта C++?   -  person JeremyP    schedule 16.05.2011
comment
Я пытался, и мне просто нужно отключить синтаксис, вот о чем этот вопрос.   -  person Aran Mulholland    schedule 16.05.2011


Ответы (2)


Значит, вы просто не совсем знакомы с синтаксисом блоков? Если да, вот краткий пример, который, надеюсь, будет иметь смысл, если вы уже знакомы с указателями на функции (синтаксис более или менее такой же, но с использованием ^ для объявления одного [создание замыкания, конечно, разные]).

Вы, вероятно, захотите настроить typedef для типов блоков, чтобы не повторять одно и то же снова и снова, но я включил примеры как для использования typedef, так и для простого помещения самого типа блока в параметры.

#import <Cocoa/Cocoa.h>

// do a typedef for the block
typedef void (^ABlock)(int x, int y);

class Receiver
{
public:
    // block in parameters using typedef
    void doSomething(ABlock block) {
        block(5, 10);
    }

    // block in parameters not using typedef
    void doSomethingToo(void (^block)(int x, int y)) {
        block(5, 10);
    }
};


int main (int argc, char const *argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    Receiver rcv;
    // pass a block
    rcv.doSomething(^(int x, int y) { NSLog(@"%d %d", x, y); });
    rcv.doSomethingToo(^(int x, int y) { NSLog(@"%d %d", x, y); });

    [pool drain];
    return 0;
}
person Community    schedule 19.05.2011
comment
Я думаю, он спрашивает, как передать блок функции C++, а не функции Objective C++. - person Cory Nelson; 20.05.2011
comment
почему создание замыкания отличается? - person Aran Mulholland; 20.05.2011
comment
@ Аран-Малхолланд Что ты имеешь в виду? Когда я говорю о создании другого замыкания, я имею в виду именно синтаксис returntype ^ (parameters) { ... }, который отличается от обычной функции, поскольку я никогда не видел, чтобы кто-то делал что-то вроде doSomething(void (int x, int y) { /* some stuff */ }) для передачи указателя функции на что-то. - person ; 20.05.2011
comment
+1 за подсказку typedef. Это делает определение функции более читабельным. - person FRotthowe; 27.05.2011

См. Использование блока в качестве аргумента функции. При объявлении вашего метода используйте синтаксис, аналогичный следующему, для объявления аргумента блока:

void theFunction(blockReturnType (^argumentName)(blockArgumentTypes));

Вызов блока выглядит как вызов функции, поэтому реализация theFunction выше, которая просто вызывает блок и возвращает его результат, будет выглядеть так:

int theFunction(int anArgument, int (^theBlock)(int)) {
    return theBlock(anArgument);
}

Этот синтаксис будет работать для C, C++ и Objective-C.

person ughoavgfhw    schedule 19.05.2011