在我的应用中,我正在使用全局调度队列和 gcd 来实现我的互联网网络。 我想在网络活动时设置网络指示器。
这是我的网络块 - >
{
[[UIApplication sharedApplication]setNetworkActivityIndicatorVisible:YES];
send sync http request
[[UIApplication sharedApplication]setNetworkActivityIndicatorVisible:NO];
}
我的问题:
我想检查是否有一块尚未执行的块!隐藏网络指示器之前。我该怎么做呢!
从另一个线程调用setNetworkActivityIndicatorVisible,这是安全的,因为我看到NetworkActivityIndicatorVisible是非原子的。
答案 0 :(得分:2)
@ DavidBemerguy的方法是一个良好的开端,但您通常希望使用dispatch_group_notify
来实现它以隐藏您的指标。也就是说,IMO,你不需要这里的GCD。您只需要一个NetworkIndicatorController
。
创建一个侦听DidStartNetworkActivity
和DidStopNetworkActivity
等通知的对象(控制器)。开始或停止时发布通知。在控制器内部,保持计数,当它达到0时,隐藏指示器。这样的事情(完全未经测试,只是在这里打字,过去几天我一直在Swift中写作,所以原谅任何丢失的分号):
·H:
extern NSString * const DidStartNetworkActivityNotification;
extern NSString * const DidStopNetworkActivityNotification;
@interface NetworkIndicatorController
- (void) start;
- (void) stop;
@end
的.m
@interface NetworkIndicatorController ()
@property (nonatomic, readwrite, assign) NSInteger count;
@end
@implementation NetworkIndicatorController
- (void)start {
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self name:DidStartNetworkActivityNotification selector:@selector(didStart:) object:nil];
[nc addObserver:self name:DidStopNetworkActivityNotification selector:@selector(didStop:) object:nil];
self.count = 0;
}
- (void)stop {
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc removeObserver:self name:DidStartNetworkActivityNotification object:nil];
[nc removeObserver:self name:DidStopNetworkActivityNotification object:nil];
}
- (void)didStart:(NSNotification *)note {
dispatch_async(dispatch_get_main_queue(), {
self.count = self.count + 1;
[[UIApplication sharedApplication]setNetworkActivityIndicatorVisible:YES];
});
}
- (void)didStop:(NSNotification *)note {
dispatch_async(dispatch_get_main_queue(), {
self.count = self.count - 1;
if (self.count <= 0) {
[[UIApplication sharedApplication]setNetworkActivityIndicatorVisible:NO];
}
});
}
您可以使用dispatch_group获得类似的东西,但我认为这更简单。调度组方法的问题是跟踪您何时执行并且不想调用dispatch_notify。我确定最终的代码并不难,但考虑所有可能的竞争条件会更加棘手。
您也可以直接在您传递的此对象的实例上直接调用-startNetworkActivity
和-stopNetworkActivity
,而不是使用通知。
答案 1 :(得分:1)
一种可能的方法是创建一组任务,然后等待它们完成。在开始和结束之间,您可以更新活动指示器。显然,您需要一些能够保留对该组的引用的对象。根据Apple文档检查此代码:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // Retain this queue somewhere accessible from the places you want to dispatch
dispatch_group_t group = dispatch_group_create(); // Retain this group somewhere accessible from the places you want to dispatch
// Add a task to the group
dispatch_group_async(group, queue, ^{
// Some asynchronous work
});
// Do some other work while the tasks execute.
disptach_sync(dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication]setNetworkActivityIndicatorVisible:YES];
}
// When you cannot make any more forward progress,
// wait on the group to block the current thread.
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
// Release the group when it is no longer needed.
disptach_sync(dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication]setNetworkActivityIndicatorVisible:NO];
}
dispatch_release(group);
请记住,您可以拥有一个单独的对象来分配您的块并跟踪您的等待。