GCD сделает большинство ваших проблем с многопоточностью тривиальными.Вы можете сделать что-то вроде этого:
- (void)mainFunction
{
// Runs your task on a background thread with default priority.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
ManipulatedObject * obj = [[ManipulatedObject alloc] init];
[obj startJob]; // I'm assuming this is sychronous.
// The callback is explicitly run on the main thread.
dispatch_async(dispatch_get_main_queue(), ^{
// Your callback here.
[obj release];
});
});
}
Это все, что вам нужно сделать, это так просто.Весь соответствующий код встроен и вместе.
Если вы хотите, чтобы ManipulatedObject
явно вызывал блок, вы можете добавить эту способность к ManipulatedObject
.Для этого вам следует:
Определить тип блока для удобства typedef void(^MyCallback)();
Добавить @property (nonatomic, copy) MyCallback block;
и @synthesize block
.Не забудьте копию.
Вызовите блок, когда вам нужно dispatch_async(dispatch_get_main_queue(), [self block]);
.
Если ваш делегат должен сделать больше, чемодин вид обратного вызова, тогда вам понадобится блок для каждого обратного вызова.Это небольшое неудобство, но оно того стоит для всех удобств, которые вы получаете.
Для более подробного объяснения блоков и GCD, посетите сеанс WWDC 2011 308.