我需要执行异步函数执行,因为它阻塞了主线程,因此UI不可用.
在查看stackoverflow中的问题后,我知道有三种方法可以执行异步功能.
一个例子:
[NSThread detachNewThreadSelector:@selector(showSpinner:) toTarget:self withObject:self.view]; // or [self performSelectorInBackground:@selector(showSpinner:) withObject:self.view]; // or NSInvocationOperation *invOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(showSpinner:) object:self.view]; NSOperationQueue *opQueue = [[NSOperationQueue alloc] init]; [opQueue addOperation:invOperation]; // or dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{ dispatch_async(dispatch_get_main_queue(),^{ [self showSpinner:self.view]; }); });
我的问题是performSelectorInBackground和detachNewThreadSelector如何返回主线程?你怎么知道他们已经完成了?
解决方法
几点想法:
>你可能希望在并发编程指南,这使得调度队列和操作队列,它们是相同的指南前面所讨论的一个令人信服的理由来检查Migrating Away From Threads.
>另外,当你深入到不同的异步操作,记住,做耗时在后台队列/线程的东西,但总调度UI的东西回到主队列.我只提到,因为你的任务,showSpinner听起来很像一个UI任务,你永远不想在后台队列/线程中做.如果它有一些“昂贵”相关的任务非UI,再细,这样做的背景,但要确保UI的东西被分派回主队列.
>除此之外,还有其他操作队列的再现,例如块操作:
NSOperationQueue *opQueue = [[NSOperationQueue alloc] init]; [opQueue addOperationWithBlock:^{ // do some slow stuff in the background here // ok,now do UI stuff in the main queue [[NSOperationQueue mainQueue] addOperationWithBlock:^{ [self showSpinner:self.view]; }]; }];
这大致相当于GCD(调度队列)再现:
dispatch_queue_t dispatchQueue = dispatch_queue_create("com.ramshad.app",0); dispatch_async(dispatchQueue,^{ // do some slow stuff in the background here // ok,now do UI stuff in the main queue dispatch_async(dispatch_get_main_queue(),^{ [self showSpinner:self.view]; }); });
有吨操作队列和调度队列(这是因为它已经讨论了数百篇关于堆栈溢出其他地方的时候,我们不应该进入这里)之间微妙的利弊,但都让你做出奇丰富的异步操作比传统的复杂性更小线程编程.
>如果您决定坚持使用线程与操作和/或调度队列(我不一定会推荐),您可能需要查看Threading Programming Guide.