Skip to content

Instantly share code, notes, and snippets.

@AlanQuatermain
Created May 5, 2011 13:48
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save AlanQuatermain/957060 to your computer and use it in GitHub Desktop.
Save AlanQuatermain/957060 to your computer and use it in GitHub Desktop.
Keep your iOS network activity indicator under control, in a *thread-safe* way. Also shows a useful means of debugging it by logging backtraces for on/off calls.
//
// KBNetworkActivityIndicator.h
// Kobov3
//
// Created by Jim Dovey on 10-03-21.
// Copyright 2010 Kobo Inc. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface KBNetworkActivityIndicator : NSObject
// these implement a counting shim over the OS's toggle on/off value
+ (void) showNetworkActivityIndicator;
+ (void) hideNetworkActivityIndicator;
@end
//
// KBNetworkActivityIndicator.m
// Kobov3
//
// Created by Jim Dovey on 10-03-21.
// Copyright 2010 Kobo Inc. All rights reserved.
//
#import "KBNetworkActivityIndicator.h"
#import <libkern/OSAtomic.h>
#import "DebuggingAids.h"
#ifndef LOG_ACTIVITY_TOGGLE_STATS
# define LOG_ACTIVITY_TOGGLE_STATS 0
#endif
NSMutableSet * gNetworkActivityStacks = nil;
@interface KBNetworkActivityIndicatorCounter : NSObject
{
volatile NSInteger _counter;
}
+ (KBNetworkActivityIndicatorCounter *) sharedCounter;
- (void) increment;
- (void) decrement;
- (void)toggleNetworkIndicator:(NSNumber *)on;
@end
#pragma mark -
@implementation KBNetworkActivityIndicator
#if LOG_ACTIVITY_TOGGLE_STATS
+ (void) initialize
{
if ( self != [KBNetworkActivityIndicator class] )
return;
gNetworkActivityStacks = [[NSMutableSet alloc] initWithCapacity: 16];
}
#endif
+ (void) showNetworkActivityIndicator
{
#if LOG_ACTIVITY_TOGGLE_STATS
@synchronized(gNetworkActivityStacks)
{
[gNetworkActivityStacks addObject: BacktraceString(3)];
}
#endif
[[KBNetworkActivityIndicatorCounter sharedCounter] increment];
}
+ (void) hideNetworkActivityIndicator
{
#if LOG_ACTIVITY_TOGGLE_STATS
@synchronized(gNetworkActivityStacks)
{
[gNetworkActivityStacks removeObject: BacktraceString(3)];
}
#endif
[[KBNetworkActivityIndicatorCounter sharedCounter] decrement];
}
@end
#pragma mark -
@implementation KBNetworkActivityIndicatorCounter
+ (KBNetworkActivityIndicatorCounter *) sharedCounter
{
static KBNetworkActivityIndicatorCounter * volatile __singleton = nil;
if ( __singleton == nil )
{
KBNetworkActivityIndicatorCounter * tmp = [[KBNetworkActivityIndicatorCounter alloc] init];
if ( OSAtomicCompareAndSwapPtrBarrier(nil, tmp, (void * volatile *)&__singleton) == false )
[tmp release];
}
return ( __singleton );
}
- (void) increment
{
if ( OSAtomicIncrement32(&_counter) > 0 )
[self performSelectorOnMainThread:@selector(toggleNetworkIndicator:) withObject:[NSNumber numberWithBool:YES] waitUntilDone:NO];
}
- (void) decrement
{
if ( OSAtomicDecrement32(&_counter) <= 0 )
{
[self performSelectorOnMainThread:@selector(toggleNetworkIndicator:) withObject:[NSNumber numberWithBool:NO] waitUntilDone:NO];
#if LOG_ACTIVITY_TOGGLE_STATS
@synchronized(gNetworkActivityStacks)
{
[gNetworkActivityStacks removeAllObjects];
}
#endif
}
}
- (void)toggleNetworkIndicator:(NSNumber *)on {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:[on boolValue]];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment