Ker*_*rrM 6 iphone multithreading cocoa-touch ios
我正在创建一个从数据库中获取一组结果的应用程序 - 我使用MBProgressHUD来显示带动画的查询进度.我使用的方法在另一个线程中执行方法时调用动画,一旦完成,它就会隐藏动画.我的问题是,在致电:
[HUD showWhileExecuting:@selector(getResults) onTarget:self withObject:nil animated:YES];
Run Code Online (Sandbox Code Playgroud)
我想,如果没有结果,则显示一条警告,说明这一点,如果有,则加载下一个视图.到目前为止,我有这个代码:
[HUD showWhileExecuting:@selector(getResults) onTarget:self withObject:nil animated:YES];
if(self.thereAreEvents) {
[self performSegueWithIdentifier:@"searchResults" sender:self];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"No results" message:@"Sorry, there are no results for your search. Please try again." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
Run Code Online (Sandbox Code Playgroud)
self.thereAreEvents
在getResults
方法结束时设置.但是,由于该方法在另一个线程中被调用,因此即使数据库中存在事件,该执行行也会继续并显示警报.
所以,从这里开始,我有两个问题:在iOS中实现等待信号机制的最简单方法是什么?在iOS中实现这种机制的最有效方法是什么?
谢谢!
zou*_*oul 11
您可以使用忙等待循环来获得快速而肮脏的解决方案:
__block BOOL finished = NO;
dispatch_async(/* global queue */, ^{
// …
finished = YES;
});
while (!finished) /* waiting */;
Run Code Online (Sandbox Code Playgroud)
在"真实"代码中,最好使用信号量:
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_async(/* global queue */, ^{
// …
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_release(sempahore);
Run Code Online (Sandbox Code Playgroud)
这比busy循环更好,因为被阻塞的线程不占用CPU时间.
最好的解决方案是防止阻塞和重新设计代码以异步工作.在您的情况下,您应该显示一个微调器并开始下载数据.数据下载完成后,您应该收到异步回调(通过块或目标/操作回调)并显示结果或显示错误警报.在这种情况下,使用繁忙的循环或信号量阻塞是一个穷人的解决方案.
您还可以考虑一个NSConditionLock
.
所以线程 1 上会是这样的:
[conditionLock lockWhenCondition:kConditionOkayToProceed];
[conditionLock unlockWithCondition:kConditionGettingResults];
[HUD show...]
[conditionLock lockWhenCondition:kConditionResultsFetched];
[conditionLock unlockWithCondition:kConditionOkayToProceed];
Run Code Online (Sandbox Code Playgroud)
在平视显示器中:
- (void)show...
{
[conditionLock lockWhenCondition:kConditionGettingResults];
// stuff here
[conditionLock unlockWithCondition:kConditionResultsFetched];
}
Run Code Online (Sandbox Code Playgroud)
尽管更好的解决方案是将块或目标/选择器传递给 HUD,HUD 将在获取结果时执行该操作。
编辑:所以你最终会得到如下代码:
[HUD showWhileExecuting:@selector(getResults)
onTarget:self
withObject:nil
animated:YES
performWhenFinished:
^{
if(self.thereAreEvents) {
[self performSegueWithIdentifier:@"searchResults" sender:self];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"No results" message:@"Sorry, there are no results for your search. Please try again." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
}];
Run Code Online (Sandbox Code Playgroud)
在平视显示器中:
- (void)showWhile... performWhenFinished:(dispatch_block_t)block
{
// all the other stuff you were going to do here, then
// eventually...
// if no guarantees, maybe just:
block();
// otherwise, if promised to dispatch to the main queue:
dispatch_async(dispatch_get_main_queue(), block);
}
Run Code Online (Sandbox Code Playgroud)
HUD 具有额外的智能,可以将 adispatch_block_t
作为最终参数,并在结果出现时调用它(无论是否保证分派回主线程或以其他方式)。
归档时间: |
|
查看次数: |
14228 次 |
最近记录: |