Created
August 10, 2012 09:44
-
-
Save jlcampana/3313037 to your computer and use it in GitHub Desktop.
Clase para crear singletons
This file contains hidden or 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
// | |
// CWLSynthesizeSingleton.h | |
// CocoaWithLove | |
// | |
// Created by Matt Gallagher on 2011/08/23. | |
// Copyright (c) 2011 Matt Gallagher. All rights reserved. | |
// | |
// Permission is given to use this source code file, free of charge, in any | |
// project, commercial or otherwise, entirely at your risk, with the condition | |
// that any redistribution (in part or whole) of source code must retain | |
// this copyright and permission notice. Attribution in compiled projects is | |
// appreciated but not required. | |
// | |
/* | |
Singletons in Cocoa | |
The solution to the encapsulation problem is to create classes that manage any global data as discreet modules. This is done through a singleton. | |
The basic recipe for making a singleton is given by Apple: Creating a Singleton Instance. | |
I personally like to put these singleton methods into a macro, which you can download in my CWLSynthesizeSingleton.h file. If you #import this header at the top of a class implementation, then all you need to do is write: | |
CWL_SYNTHESIZE_SINGLETON_FOR_CLASS(MyClassName); | |
inside the @implementation MyClassName declaration and your class will become a singleton. You will also need to add the line: | |
CWL_DECLARE_SINGLETON_FOR_CLASS(MyClassName) | |
in the method declarations section of the header file for MyClassName so the singleton accessor method can be found from other source files if they #import the header. | |
Once your class is a singleton, you can access the instance of it using the line: | |
[MyClassName sharedMyClassName]; | |
Note: A singleton does not need to be explicitly allocated or initialized (the alloc and init methods will be called automatically on first access) but you can still implement the default init method if you want to perform initialization. | |
*/ | |
#import <objc/runtime.h> | |
#define CWL_DECLARE_SINGLETON_FOR_CLASS_WITH_ACCESSOR(classname, accessorMethodName) \ | |
+ (classname *)accessorMethodName; | |
#if __has_feature(objc_arc) | |
#define CWL_SYNTHESIZE_SINGLETON_RETAIN_METHODS | |
#else | |
#define CWL_SYNTHESIZE_SINGLETON_RETAIN_METHODS \ | |
- (id)retain \ | |
{ \ | |
return self; \ | |
} \ | |
\ | |
- (NSUInteger)retainCount \ | |
{ \ | |
return NSUIntegerMax; \ | |
} \ | |
\ | |
- (oneway void)release \ | |
{ \ | |
} \ | |
\ | |
- (id)autorelease \ | |
{ \ | |
return self; \ | |
} | |
#endif | |
#define CWL_SYNTHESIZE_SINGLETON_FOR_CLASS_WITH_ACCESSOR(classname, accessorMethodName) \ | |
\ | |
static classname *accessorMethodName##Instance = nil; \ | |
\ | |
+ (classname *)accessorMethodName \ | |
{ \ | |
@synchronized(self) \ | |
{ \ | |
if (accessorMethodName##Instance == nil) \ | |
{ \ | |
accessorMethodName##Instance = [super allocWithZone:NULL]; \ | |
accessorMethodName##Instance = [accessorMethodName##Instance init]; \ | |
method_exchangeImplementations(\ | |
class_getClassMethod([accessorMethodName##Instance class], @selector(accessorMethodName)),\ | |
class_getClassMethod([accessorMethodName##Instance class], @selector(cwl_lockless_##accessorMethodName)));\ | |
method_exchangeImplementations(\ | |
class_getInstanceMethod([accessorMethodName##Instance class], @selector(init)),\ | |
class_getInstanceMethod([accessorMethodName##Instance class], @selector(cwl_onlyInitOnce)));\ | |
} \ | |
} \ | |
\ | |
return accessorMethodName##Instance; \ | |
} \ | |
\ | |
+ (classname *)cwl_lockless_##accessorMethodName \ | |
{ \ | |
return accessorMethodName##Instance; \ | |
} \ | |
\ | |
+ (id)allocWithZone:(NSZone *)zone \ | |
{ \ | |
return [self accessorMethodName]; \ | |
} \ | |
\ | |
- (id)copyWithZone:(NSZone *)zone \ | |
{ \ | |
return self; \ | |
} \ | |
- (id)cwl_onlyInitOnce \ | |
{ \ | |
return self;\ | |
} \ | |
\ | |
CWL_SYNTHESIZE_SINGLETON_RETAIN_METHODS | |
#define CWL_DECLARE_SINGLETON_FOR_CLASS(classname) CWL_DECLARE_SINGLETON_FOR_CLASS_WITH_ACCESSOR(classname, shared##classname) | |
#define CWL_SYNTHESIZE_SINGLETON_FOR_CLASS(classname) CWL_SYNTHESIZE_SINGLETON_FOR_CLASS_WITH_ACCESSOR(classname, shared##classname) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment