@ Подход DavidBemerguy - хорошее начало, но вы, как правило, хотите его реализовать с помощью dispatch_group_notify
, чтобы скрыть индикатор. Тем не менее, ИМО, вам здесь не нужен 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 имеет простой ответ, если вы идете на один уровень выше и используете NSOperationQueue. Отправка блока на него действительно не сложнее, чем GCD, и это дает вам гораздо лучший контроль над операциями. –
@PhillipMills спасибо, я проверю документацию – david
@PhillipMills, но как насчет второго вопроса – david