aboutsummaryrefslogtreecommitdiff
path: root/Foundation
diff options
context:
space:
mode:
authorGravatar gtm.daemon <gtm.daemon@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3>2012-08-13 21:30:12 +0000
committerGravatar gtm.daemon <gtm.daemon@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3>2012-08-13 21:30:12 +0000
commit75cd2405924bae4e378a8ab74d0a03c00351f937 (patch)
tree5e417f039f4d88a7f867a393929c84552fcc074b /Foundation
parenta9a0b39d1ed6381d768bda09bd5dd64ec7621a20 (diff)
[Author: grobbins]
Modernize GTMObjectSingleton: Use dispatch_once, make ARC compatible, remove non-allocation NSObject methods, remove dependence on GTMDevAssert, add link to Chris Hanson's discussion of singletons, add comment discouraging developers from using this header file. R=thomasvl APPROVED=thomasvl DELTA=75 (24 added, 39 deleted, 12 changed)
Diffstat (limited to 'Foundation')
-rw-r--r--Foundation/GTMObjectSingleton.h87
1 files changed, 36 insertions, 51 deletions
diff --git a/Foundation/GTMObjectSingleton.h b/Foundation/GTMObjectSingleton.h
index fe1cc75..eeb9ec7 100644
--- a/Foundation/GTMObjectSingleton.h
+++ b/Foundation/GTMObjectSingleton.h
@@ -1,6 +1,6 @@
//
// GTMObjectSingleton.h
-// Macro to implement methods for a singleton
+// Macro to implement a creation method for a singleton
//
// Copyright 2005-2008 Google Inc.
//
@@ -17,56 +17,41 @@
// the License.
//
-#import "GTMDefines.h"
-
-/// This macro implements the various methods needed to make a safe singleton.
//
-/// This Singleton pattern was taken from:
-/// http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/chapter_3_section_10.html
-///
-/// Sample usage:
-///
-/// GTMOBJECT_SINGLETON_BOILERPLATE(SomeUsefulManager, sharedSomeUsefulManager)
-/// (with no trailing semicolon)
-///
+// This file is still around for compatibility with apps relying on its macro,
+// but given how simple this is, there is not a compelling reason for any app to
+// use this macro.
+//
+// For a reasonable discussion of Objective-C singletons, see
+// http://eschatologist.net/blog/?p=178
+//
+// Sample usage:
+//
+// GTMOBJECT_SINGLETON_BOILERPLATE(SomeUsefulManager, sharedSomeUsefulManager)
+// (with no trailing semicolon)
+//
+
+#if NS_BLOCKS_AVAILABLE
+
+#define GTMOBJECT_SINGLETON_BOILERPLATE(_object_name_, _shared_obj_name_) \
++ (_object_name_ *)_shared_obj_name_ { \
+ static _object_name_ *obj; \
+ static dispatch_once_t onceToken; \
+ dispatch_once(&onceToken, ^{ \
+ obj = [[self alloc] init]; \
+ }); \
+ return obj; \
+}
+
+#else
+
#define GTMOBJECT_SINGLETON_BOILERPLATE(_object_name_, _shared_obj_name_) \
-static _object_name_ *z##_shared_obj_name_ = nil; \
-+ (_object_name_ *)_shared_obj_name_ { \
- @synchronized(self) { \
- if (z##_shared_obj_name_ == nil) { \
- /* Note that 'self' may not be the same as _object_name_ */ \
- /* first assignment done in allocWithZone but we must reassign in case init fails */ \
- z##_shared_obj_name_ = [[self alloc] init]; \
- _GTMDevAssert((z##_shared_obj_name_ != nil), @"didn't catch singleton allocation"); \
- } \
- } \
- return z##_shared_obj_name_; \
-} \
-+ (id)allocWithZone:(NSZone *)zone { \
- @synchronized(self) { \
- if (z##_shared_obj_name_ == nil) { \
- z##_shared_obj_name_ = [super allocWithZone:zone]; \
- return z##_shared_obj_name_; \
- } \
- } \
- \
- /* We can't return the shared instance, because it's been init'd */ \
- _GTMDevAssert(NO, @"use the singleton API, not alloc+init"); \
- return nil; \
-} \
-- (id)retain { \
- return self; \
-} \
-- (NSUInteger)retainCount { \
- return NSUIntegerMax; \
-} \
-- (oneway void)release { \
-} \
-- (id)autorelease { \
- return self; \
-} \
-- (id)copyWithZone:(NSZone *)zone { \
- GTM_UNUSED(zone); \
- return self; \
-} \
++ (_object_name_ *)_shared_obj_name_ { \
+ static _object_name_ *obj; \
+ if (obj == nil) { \
+ obj = [[self alloc] init]; \
+ } \
+ return obj; \
+}
+#endif // NS_BLOCKS_AVAILABLE