diff options
author | gtm.daemon <gtm.daemon@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3> | 2012-08-13 21:30:12 +0000 |
---|---|---|
committer | gtm.daemon <gtm.daemon@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3> | 2012-08-13 21:30:12 +0000 |
commit | 75cd2405924bae4e378a8ab74d0a03c00351f937 (patch) | |
tree | 5e417f039f4d88a7f867a393929c84552fcc074b /Foundation | |
parent | a9a0b39d1ed6381d768bda09bd5dd64ec7621a20 (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.h | 87 |
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 |