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

В Objective C, что эквивалентно передаче указателя функции в C?

@implementation ThisObject

-(void)start {

       SomeOtherObject *someOtherObject = [SomeOtherObject alloc];

       [someOtherObject doSomethingAndCallThisFunctionWhenUrDone:myCallBackFunction :self];

}

-(void)myCallBackFunction {

       // :)

}

В принципе, как я могу сделать эту работу?

4b9b3361

Ответ 1

Существует четыре способа сделать обратный вызов:

  • Указатель функций Вы можете сделать указатель на функцию, если хотите, но это не рекомендуется. Это было сделано так же, как и в C. Проблема заключается в том, что вы не можете использовать указатель на метод Objective-C. Это выглядит примерно так:

    void callback(/* Some args */) {
        // Some callback.
    }
    
    - (void)doSomethingAndCallThisFunctionWhenDone:(void(*)(/* Some args */))func {
    
        // Do something.
    
        if (func)
            func(/* Some args */);
    }
    
    - (void)start {
        [self doSomethingAndCallThisFunctionWhenDone:&callback];
    }
    
  • Селекторы. Вы можете использовать -performSelector:. Это выглядит так:

    - (void)doSomethingAndCallTarget:(id)target withSelector:(SEL)sel {
    
        // Do something.
    
        [target performSelector:sel];
    }
    
    - (void)start {
    
        SomeOtherObject * someOtherObject = [[SomeOtherObject alloc] init];
    
        [self doSomethingAndCallTarget:someOtherObject withSelector:@selector(MyCallback)];
    }
    
  • Делегаты. Используйте делегат. Это похоже на UITableViewDelegate/UITableViewDataSource. См. Apple docs здесь. Вы можете сделать это следующим образом:

    - (void)doSomethingDelegate:(id<MyCallbackObject>)delegate {
    
        [delegate retain];
    
        // Do something.
    
        [delegate performMyCallback];  // -performMyCallback must be declared in the MyCallbackObject protocol and implemented by SomeOtherObject.
    
        [delegate release];
    }
    
    - (void)start {
    
        id<MyCallbackObject> someOtherObject = [[SomeOtherObject alloc] init];
    
        [self doSomethingDelegate:someOtherObject];
    
        [someOtherObject release];
    }
    
  • Блоки. Предпочтительным способом для обратных вызовов является использование блоков. Они доступны только для iOS 4.0+ или Mac OS X 10.6+. Это выглядит примерно так:

    - (void)doSomethingAndCallThisBlockWhenDone:(void(^)(/* Some args */))block {
    
        [block copy];
    
        // Do something.
    
        if (block)
            block(/* Some args */);
    
        [block release];
    }
    
    - (void)start {
        [self doSomethingAndCallThisBlockWhenDone:^void(/* Some args */){   // Return type and arguments may be omitted if you don't have any.
            // Your callback
        }];
    }
    

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

Последнее, если вы используете блок, вы захотите использовать typedef, поэтому вам не нужно вводить непонятные типы блоков, такие как void(^)(/* Some args */) все время. typedef может выглядеть так:

typdef void(^MyCallback)(/* Some args */);

Затем вы можете объявить свой метод следующим образом:

- (void)doSomethingAndCallThisBlockWhenDone:(MyCallback)block;

Update:

Я показал более подробную информацию о том, как реализовать различные методы (см. выше).

Ответ 2

Вы об этом говорите?

-(void)callSomePassedSelector:(SEL)callbackSelector {
    [someObjectThatRespondesToThisSelector performSelector:callbackSelector];
}

Я предполагаю, что вы хотите сохранить его и называть его позже, но это должно предоставить вам всю необходимую информацию о том, как пройти и называть его. Существуют и другие способы вызова селектора, см. Более здесь

Ответ 3

im немного запутался в том, о чем вы говорите, но это ли это?

[self performSelector:@selector(myCallFunction)];