Как отправить блок с параметром в основную очередь или поток

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

Скажем, у меня есть два блока в этом псевдокоде, удобно названные blockA и blockB. Первый - это простой блок без параметров, который просто печатает строку. Второй принимает один параметр xyz типа id:

void (^blockA){ NSLog(@"Doing something"); };
void (^blockB)(id xyz){ [xyz doSomething]; };

При запуске blockA я бы сделал что-то вроде blockA();, или когда я хочу настроить таргетинг на основную очередь / поток, я использую метод dispatch_sync или _async:

dispatch_sync(dispatch_get_main_queue(), blockA);

Но хотя я знаю, как отправлять blockB с параметром типа blockB(someObject);, я не могу понять, как явно вызвать его в основном потоке. Я искал что-то вроде следующей строки, но, конечно, это не, как это работает:

dispatch_sync (dispatch_get_main_queue, blockB, someObject);

Теперь я попытался обернуть блок другим блоком, но, честно говоря, это выглядело неправильно, и мне казалось, что это вызывает больше проблем, чем решает. Есть ли что-то кроме упаковки блоков для отправки одного блока с одним или несколькими параметрами в основной очереди / потоке?


person epologee    schedule 09.09.2011    source источник


Ответы (2)


Неа. Обертывание блоков - это именно то, что вам нужно делать в этом случае. В коде:

void (^block)(id someArg) = someBlock;
id object = someObject;
dispatch_async(dispatch_get_main_queue(), ^{
    block(someObject);
});

Сначала это может показаться немного странным, но этот стиль значительно упрощает диспетчерские API, а автоматическое сохранение захваченных переменных делает это возможным. Я немного удивлен, что у вас возникли проблемы. Кем они были?

person kperryua    schedule 09.09.2011
comment
У меня ужасный сбой веб-блокировки, который я не могу проследить до его источника: Пытался получить веб-блокировку из потока, отличного от основного потока или веб-потока. Это может быть результатом вызова UIKit из вторичного потока. Сбой сейчас ... Вот почему я устраняю проблему, потому что любой код, работающий в этот момент, должен был выполняться в основном потоке. Я думал, что это могло быть причиной вложенности блоков, но из того, что вы говорите, похоже, что это что-то еще. - person epologee; 09.09.2011
comment
Какая разница в простом использовании объекта в блоке? И я думаю, что вы хотели определить dispatch_async(dispatch_get_main_queue(), ^{ block(object);});? - person izzy; 22.01.2015

К блокам тоже привыкаю. Честно говоря, я не вижу ничего чище / лучше, чем:

dispatch_async(dispatch_get_main_queue(), ^{blockb(someObj);});
person Cliff    schedule 09.09.2011