Дизайн обратного вызова какао: лучшая практика [закрывается]

5
задан Akusete 6 July 2010 в 01:24
поделиться

2 ответа

Я бы выбрал longRunningProcess2 вместо longRunningProcess3 просто потому, что это легче понять, если вы видите объявления методов в протоколе, а не полагаясь на документацию, чтобы выяснить, каковы аргументы метода обратного вызова.

Я хотел бы добавить, что Apple использует блоки для обратных вызовов в API, новом для 10.6, что дает вам еще один вариант, если вы не поддерживаете 10.5 или более раннюю версию.

Блочный подход будет выглядеть так:

-(void) longRunningProcessWithSuccessHandler:(void(^)(ReturnObject* value))successHandler
                                errorHandler:(void(^)(NSError* error))errorHandler
                             progressHandler:(void(^)(NSInteger completed, NSInteger total))progressHandler;
{
    NSInteger totalItems = 10;
    NSInteger item = 0;
    for(item = 0; item < totalItems; ++item){
        [self processItem:item];
        progressHandler(item, totalItems);
    }

    BOOL wasSuccessful = ?;
    if(wasSuccessful){
        ReturnObject* value = ?;
        successHandler(value);
    } else {
        NSError* error = ?;
        errorHandler(error);
    }
}

И вы должны вызвать метод следующим образом:

[SomeObj longRunningProcessWithSuccessHandler:^(ReturnObject* value) { [self showReturnObject:value]; }
                                 errorHandler:^(NSError* error){ [self presentError:error]; }
                              progressHandler:^(NSInteger completed, NSInteger total) { [self updateProgressToPercent:(double)completed/total]; }];
5
ответ дан 14 December 2019 в 04:29
поделиться

Я бы пошел с одним маршрутом протокола, похожим на ваш вариант CallbackProtocolGeneric , за исключением того, что я бы расширил его так, чтобы он выглядел примерно так:

- (void) operation:(id)operation didFinishWithReturnValue:(id)returnValue;
- (void) operation:(id)operation didFailWithError:(NSError *)error;
- (void) operation:(id)operation hasCompleted:(NSInteger)progress ofTotal:(NSInteger)total;

Так что это похоже на вариант 1 в том, что у вас есть единый протокол, но, как и вариант 2, вы передаете больше информации. При необходимости вы можете расширить его, добавив что-то вроде:

- (void) operation:(id)operation didFinishStep:(NSInteger)stepNumber withReturnValue:(id)returnValue;
- (void) operation:(id)operation didFailStep:(NSInteger)stepNumber withError:(NSError *)error;
- (void) operation:(id)operation step:(NSInteger)step hasCompleted:(NSInteger)progress ofTotal:(NSInteger)total;

Параметр «step» может быть некоторым значением, которое указывает, какие из «10+ длинных операций» выполняет этот конкретный объект.

Конечно, этот совет является очень общим, поскольку в вашем вопросе также отсутствует конкретная информация, но, вероятно, я бы пошел именно в этом направлении (не зная больше).

3
ответ дан 14 December 2019 в 04:29
поделиться