функция возвращает значение из блока - PullRequest
1 голос
/ 04 ноября 2011

Что если у меня есть функция, которая возвращает int и возвращаемое значение int берется из блока?

Например:

- (int) queryForKey:(NSString *)aKey view:(UIButton *)aView countView:(UIView *)aCountView counter:(int) count {
    //some initialization
    [query countObjectsInBackgroundWithBlock:^(int number, NSError * error) {
        [aCountView addSubview:self.generateCountLabel];

        if (number > 0){
            [aView setUserInteractionEnabled:YES];
            [aView setEnabled:YES];
        }
        //return number; //doing this will generate an error
    }];
}

также еще один вопрос: что если у меня есть int, переданный в качестве аргумента функции выше, и я хотел бы присвоить ему значение. Возможно ли что-то подобное?

Ответы [ 3 ]

1 голос
/ 04 ноября 2011

Проблема в том, что у вас есть синхронный метод (тот, который хочет немедленно вернуть значение), который должен возвращать значение, полученное из асинхронного метода (тот, который работает в другом потоке).

Существует несколько способов исправить это:

  • дождаться завершения метода countObjectsInBackgroundWithBlock: используйте шаблон __block, как описано @simonpie.

  • замените return number; вызовом чего-либо, заинтересованного в полученном номере.Это также означает, что queryForKey:view:countView:, скорее всего, вернет void.

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

Обратите внимание, что вы не можете перезаписывать классы UIKit ни на чем, кроме основного потока.Если этот блок выполняется в фоновом потоке, то выполнение того, что вы делаете в этом блоке, недопустимо.

1 голос
/ 04 ноября 2011

Ну, у вашего блока нет возвращаемого значения, он возвращает void.

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

0 голосов
/ 29 ноября 2012

Я нашел лучшее решение.Надеюсь, это поможет кому-то еще, кто наткнется на вопрос.Я бы реализовал решение для вашего кода следующим образом:

- (int) queryForKey:(NSString *)aKey view:(UIButton *)aView countView:(UIView *)aCountView counter:(int) count {
    dispatch_semaphore_t sema = dispatch_semaphore_create(0);
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    __block int number;

    //some initialization
    [query countObjectsInBackgroundWithBlock:^(int number, NSError * error) {
        dispatch_async(queue, ^{
            [aCountView addSubview:self.generateCountLabel];

            if (number > 0){
                [aView setUserInteractionEnabled:YES];
                [aView setEnabled:YES];
            }
            dispatch_semaphore_signal(sema);
        });
    }];
    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
    return number; //doing this will no longer generate an error
}

Затем инкапсулируйте ваш вызов с другим dispatch_async, чтобы ваш ожидающий вызов семафора не блокировал основной поток.

dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_async(queue, ^{
    [self queryForKey:@"AKey" view:myView countView:myCountView counter:aCounter];
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...