Я бы выбрал 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]; }];
Я бы пошел с одним маршрутом протокола, похожим на ваш вариант 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+ длинных операций» выполняет этот конкретный объект.
Конечно, этот совет является очень общим, поскольку в вашем вопросе также отсутствует конкретная информация, но, вероятно, я бы пошел именно в этом направлении (не зная больше).