Created
June 30, 2011 22:18
-
Star
(117)
You must be signed in to star a gist -
Fork
(21)
You must be signed in to fork a gist
-
-
Save lukeredpath/1057420 to your computer and use it in GitHub Desktop.
Macro for creating your "shared instance" using GCD
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@implementation MySharedThing | |
+ (id)sharedInstance | |
{ | |
DEFINE_SHARED_INSTANCE_USING_BLOCK(^{ | |
return [[self alloc] init]; | |
}); | |
} | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define DEFINE_SHARED_INSTANCE_USING_BLOCK(block) \ | |
static dispatch_once_t pred = 0; \ | |
__strong static id _sharedObject = nil; \ | |
dispatch_once(&pred, ^{ \ | |
_sharedObject = block(); \ | |
}); \ | |
return _sharedObject; \ |
No, it acts like a traditional singleton in that respect - only one can ever be created.
This code is error in Xcode 4.6
GCDSingleton.h:7:25: note: expanded from macro 'DEFINE_SHARED_INSTANCE_USING_BLOCK'
return _sharedObject; \
Last \
is not need.
Thank you for sharing such a great technique! Here is a slightly modified version:
#define SHARED_INSTANCE(...) ({\
static dispatch_once_t pred;\
static id sharedObject;\
dispatch_once(&pred, ^{\
sharedObject = (__VA_ARGS__);\
});\
sharedObject;\
})
It allows two forms of shared object initialization: one-line
+ (instancetype) sharedInstance {
return SHARED_INSTANCE( [[self alloc] init] );
}
// after pre-processing:
+ (instancetype) sharedInstance {
return ({
static dispatch_once_t pred;
static id sharedObject;
dispatch_once(&pred, ^{
sharedObject = ( [[self alloc] init] );
});
sharedObject;
});
}
and multi-line (notice curly braces around the block of code):
+ (instancetype) sharedInstance {
return SHARED_INSTANCE({
NSLog(@"creating shared instance");
CGFloat someValue = 84 / 2.0f;
[[self alloc] initWithSomeValue:someValue]; // no return statement
});
}
// after pre-processing:
+ (instancetype) sharedInstance {
return ({
static dispatch_once_t pred;
static id sharedObject;
dispatch_once(&pred, ^{
sharedObject = ({
NSLog(@"creating shared instance");
CGFloat someValue = 84 / 2.0f;
[[self alloc] initWithSomeValue:someValue];
});
});
sharedObject;
});
}
It can be used in the right part of an assignment as well:
- (void) someMethod {
MethodPrivateHelper *helper = SHARED_INSTANCE( [[MethodPrivateHelper alloc] init] );
// do smth with the helper
}
This modification utilizes two language features: GCC compound expressions extension, which is also supported by Clang, and C99 variadic macros support.
I am afraid that in this way it can't prevent creating multiple instances by 'alloc'.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
What if the sharedInstance is destroyed anywhere? Can it be created again?