Какао способ делать приложения с делегатами - PullRequest
1 голос
/ 10 января 2012

У меня есть метод, в котором я хочу выполнить заданную задачу, однако асинхронные команды и делегаты затрудняют это

Я могу сделать это:

- (void) fooPart1 
{
    ...
    SomeAssynchronousMethos * assync = [[SomeAssynchronousMethos alloc] init];
    assync.delegate = self;
    [assync start];

}

- (void) fooPart2
{
   ...
   possibly some other assync
}

- (void)someAssynchronousMethosDelegateDidiFinish
{
    [self fooPart2];
}

Но это не такнет ли способа сделать кузнеца.вот так

- (void) foo
{
    ...
    SomeAssynchronousMethos * assync = [[SomeAssynchronousMethos alloc] init];
    assync.delegate = self;
    [assync start];

    wait for signal, but class is not blocked
    ...
    possibly some other assync

}

- (void)someAssynchronousMethosDelegateDidiFinish
{
    continue in foo after [assync start]
}

Мне не нравится идея разбить функцию на 2 или более частей, но так ли это, как это делается в какао?или есть лучшая практика?

, почему я не люблю эту концепцию и ищу лучший способ сделать это:

  • Допустим, я хочуиспользуйте переменную только для выполнения задачи - если у меня есть все в одной функции, я просто использую ее, и чем переменная умирает, когда я покидаю функцию, если она разбивается, мне нужно как-то держать переменную, пока она не завершится
  • код становится фрагментированным и становится все труднее читать и поддерживать
  • может привести к ошибке
  • Я получаю набор функций части, который должен вызываться точноЧтобы выполнить одну задачу (для которой одна функция была бы более подходящей)

я использовал для создания потока и выполнения там только синхронных вызовов, но не все поддерживают синхронный вызов

было бы неплохо иметь что-то вроде

- (void) foo
{
    ...
    int smth = 5;
    SomeAssynchronousMethos * assync = [[SomeAssynchronousMethos alloc] init];
    assync.delegate = self;
    @freez([assync start]);
    // when freez - the local function variables are frozen 
    // (next commands in function are not excuted until unfreez)
    // from outer look, it looks like the function finished      
    // however when unfreeze, it is called from this point on

    //int smth is still 5
}

- (void)someAssynchronousMethosDelegateDidiFinish
{
    @unfreez([assync start]);
}

, когда выполнение достигнет freez, в нем будут храниться все локальные переменные, выделенные в функции, а при вызове unfreez будет продолжаться fr.в тот момент, когда он был заморожен с помощью этой команды

1 Ответ

4 голосов
/ 10 января 2012

Это похоже на идеальное применение обработчика завершения block .

Измените ваш метод start, чтобы взять параметр, который является блоком, и вызвать его так:

- (void) fooPart1 
{
    ...
    SomeAssynchronousMethos * assync = [[SomeAssynchronousMethos alloc] init];
    [assync startOnComplete: ^(NSError* error) // example, you can have any params or none
        {
            // handle error if not nil
            if (error != nil)
            {
                // do something with it
            }
            // code to do on completion
        }]; 
}

Ваш метод запуска будет выглядеть примерно так

-(void) startOnComplete: (void(^)(NSError*)) completionBlock
{
    // copy the block somewhere
    theSavedCompletionBlock = [completionBlock copy];
    // kick off async operation
}

-(void) someMethodThatRunsAttheEndOfTheAsyncOp
{
    theSavedCompletionBlock(nilOrError);
    [theSavedCompletionBlock release];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...