mikeash.com pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html commentshttp://www.mikeash.com/?page=pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html#commentsmikeash.com Recent CommentsThu, 28 Mar 2024 15:14:25 GMTPyRSS2Gen-1.0.0http://blogs.law.harvard.edu/tech/rsseschatz - 2013-11-28 11:15:41http://www.mikeash.com/?page=pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html#commentsHi Mike, <br /> <br />It's me again. <br />You say that Martin Schuerrer's swizzling version is fine but how do we sure that <b>method_exchangeImplementations</b> is thread-safe with any message call to the method to be swizzled? Would not it be possible that another thread could see half modified pointer to the method and crash? <br /> <br />Thanks82dc2e9afefcf112f632bbd27035a403Thu, 28 Nov 2013 11:15:41 GMTeschatz - 2013-11-27 16:00:50http://www.mikeash.com/?page=pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html#commentshi Mike, <br /> <br />For the GCD version, how do we make sure that foo is not in a partially modified while another thread is about to assign new value to it? Could dispatch_once guarantee this? <br /> <br />I assume that <b>primitive types</b>(int,char,pointers i.e.) are assigned in an atomic way but i also remember your statement that access to <b>* any pieces*</b> of shared memory must be synchronized; <br /> <br /><div class="blogcommentquote"><div class="blogcommentquoteinner">"In standard multithreaded code, you must synchronize access to any pieces of shared memory, usually by using a lock."</div></div><a href="http://www.mikeash.com/pyblog/friday-qa-2009-07-10-type-specifiers-in-c-part-3.html">http://www.mikeash.com/pyblog/friday-qa-2009-07-10-type-specifiers-in-c-part-3.html</a> <br /> <br />So, what is the contract about atomicity of assignments/reads of a variable? Are there any documents,references from Apple? <br /> <br />Thanks05aa40180c5266b6a9201e0a9cf3f627Wed, 27 Nov 2013 16:00:50 GMTdongzee - 2013-03-20 07:21:51http://www.mikeash.com/?page=pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html#commentsIn fact,I'd like the way by using dispatch_once.But now I meet a trouble: both considering thread-safe, loop for 1000 or more times, @synchronized cost a little less time than dispatch_once. It's Unexpected。Why?88ed2ea3ed2ea909a82ab3460f8b61ccWed, 20 Mar 2013 07:21:51 GMTmikeash - 2012-11-02 15:04:12http://www.mikeash.com/?page=pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html#commentsUsing self in a block only creates a retain cycle if the block is long-lived. In this case, the block is never even copied to the heap, much less kept alive for a long time.cc6c19521b5274d221f058e4807aa51dFri, 02 Nov 2012 15:04:12 GMTSP - 2012-10-30 14:42:00http://www.mikeash.com/?page=pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html#commentsHi Mike, Thanks a lot for the article.Inside the block you are using "self". Will not create classic retain cycle? Self will hold block &amp; block will hold self. <br /> <br />+ (id)sharedFoo <br />&nbsp;&nbsp;&nbsp;&nbsp;{ <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static dispatch_once_t pred; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static Foo *foo = nil; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dispatch_once(&amp;pred, ^{ foo = [[self alloc] init]; }); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return foo; <br />&nbsp;&nbsp;&nbsp;&nbsp;} <br /> <br />Is not it better to do it like this? <br />+ (id)sharedFoo <br />&nbsp;&nbsp;&nbsp;&nbsp;{ <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static dispatch_once_t pred; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static Foo *foo = nil; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dispatch_once(&amp;pred, ^{ foo = [[Foo alloc] init]; }); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return foo; <br />&nbsp;&nbsp;&nbsp;&nbsp;} <br /> <br />Regards, <br />SP6e004e50d2f506f2ab2f14cf3d6704dcTue, 30 Oct 2012 14:42:00 GMTmikeash - 2011-04-27 02:15:38http://www.mikeash.com/?page=pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html#commentsThat looks fine, the only reason not to use it would just be because the code ends up being slightly more complicated. Regarding performance, I'm going to guess that the only performance consequence to the simpler version will be having more code in the instruction cache, as branch prediction will probably make the if statement itself free.ce0e5ddb86943504ae679fc3c8a61b4cWed, 27 Apr 2011 02:15:38 GMTMartin Schuerrer - 2011-04-26 23:13:36http://www.mikeash.com/?page=pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html#commentsWhy not squeeze every last bit of performance out of the code and swizzle the sharedSingleton method after initialization (in the last line of the dispatch_once block)? <br /> <br /><a href="https://gist.github.com/943369">https://gist.github.com/943369</a>bab248e2a7018fc3a9710db56ac64598Tue, 26 Apr 2011 23:13:36 GMTNikita Zhuk - 2009-10-10 16:15:57http://www.mikeash.com/?page=pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html#commentsAdditional downside of using Singletons is that they make unit testing very complicated or impossible if the code under test is calling methods of a global Singleton instance. A much better option is to declare all dependencies explicitly and inject dependencies as part of object graph construction. You can still have only one instance of some class (e.g. NSFileManager), but that's just a feature of your object graph construction code - you don't have to enforce it. Now if you want to mock your file system in unit tests, just pass your MockFileManager instead.5631bce94d9f3c0f997243f1c7e2f191Sat, 10 Oct 2009 16:15:57 GMTmikeash - 2009-10-08 02:46:37http://www.mikeash.com/?page=pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html#commentsCFBundleRef isn't really a destroyable singleton, since you can have more than one. It's more like Brent Royal-Gordon's idea of uniqued objects. However, the two concepts are very similar. In both cases, you're returning an existing object when appropriate, letting objects be destroyed when no longer referenced, with the difference being only in how many instances you allow for.b9fccfc29b2e5d6e47bd876545d4d573Thu, 08 Oct 2009 02:46:37 GMTPaul Marks - 2009-10-08 01:55:10http://www.mikeash.com/?page=pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html#commentsA good example of your "destroyable singletons" is the concept (and implementation!) behind a CFBundleRef. Note that NSBundle does not share the behavior of being deallocated when client code is done; they live forever, but a CFBundleRef will be freed.b312851e9f48589b0ffa7fe461512969Thu, 08 Oct 2009 01:55:10 GMTmikeash - 2009-10-05 00:30:31http://www.mikeash.com/?page=pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html#commentsPlease understand, I'm not criticizing your idea of having a universal singleton class which you can subclass to get singleton-ness. I don't think it's particularly necessary (if you're creating that many singletons, you're probably doing something wrong) but there's nothing bad about it. <br /> <br />What I'm criticizing is two things: <br /> <br />1) That your initial proposal somehow had merit just because it was one step along a path to this universal singleton class. That's illogical. A step along a path does not have merit just because the end of the path does. <br /> <br />2) That associated objects on NSApp are better than static globals. <br /> <br />#1 I don't think needs any further explanation. If it's not obvious to you, then I can't convince you otherwise. The claim is a simple non sequitur. <br /> <br />#2 just makes no sense to me. Here is why I think that a static global is better: <br /> <br />- Works even when NSApp is not yet initialized. <br /> <br />- It's much clearer code. <br /> <br />- It's quite possibly faster, especially if you don't need to be thread safe. <br /> <br />- It will use less memory, since associated objects currently incur a 2kB memory cost for each object that has associated references on it. It's unlikely that anything else will use associated references on NSApp, so you'll cause that cost yourself. <br /> <br />- It works on any version of Mac OS X, not just 10.6+. <br /> <br />- It works for Foundation-only programs. <br /> <br />And for reasons why associated objects are better, I'm coming up completely empty. I can't see a single thing about it that's better. <br /> <br />Your comment that NSApp is the root of everything is nonsensical. You can have perfectly workable Objective-C programs that never have an NSApp. Global variables are how you do this in C. Trying to use HTML concepts in C just makes no sense. <br /> <br />If you can come up with an actual <i>concrete</i> advantage to your approach I'll certainly consider it, but so far it's nothing but handwaving.4b14e59b021c368e1b2161733564581cMon, 05 Oct 2009 00:30:31 GMTLinan Wang - 2009-10-04 23:11:36http://www.mikeash.com/?page=pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html#commentsSeems we have a taste dispute. <br />As far as I concern, my method is better in terms of code reuse. With the help of the class SingletonHelper, I need only additional 2 lines of codes to implement singleton on any classes. Of course it does cost something, a self-defined convention that all associated values of NSApp, starting with "shared", are singleton instances within the scope of an application. The trade-off, including little bit speed, is considered worthy. <br />I don't understand why you think static globals are prettier than associated values with NSApp? Singleton instances, after all, should be only available instances of certain classes within the scope of a running instance of NSApplication. Therefore, conceptually it's acceptable (if not perfectly) to bind those instances with NSApp. It is possible, as you suggested, to use a static global nsmutabledctionary to hold these singleton instances. But it is conceptually redundant. NSApp is like the "document" nod in a HTML dom, it's the root of everything. Is it conceptually clearer for you treat singleton instances "rootless" by using static globals?f2a77904fdce45da78360c15cafff737Sun, 04 Oct 2009 23:11:36 GMTmikeash - 2009-10-04 02:11:53http://www.mikeash.com/?page=pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html#commentsBeing "one step" towards this idea of a better singleton is pointless. Either the "one step" stands up on its own merit, or it doesn't. In this case, it doesn't. If you see the Ruby way as being superior, then you need to do all of it. Modifying code in ways which make it possible but which aren't useful in their own right really isn't very useful. <br /> <br />I have to say that I really don't see the point of using an associated object even in your more complicated case here. You're basically just using associated objects on NSApp as an ugly and dangerous thread-safe substitute for an NSMutableDictionary. Why not just use @synchronized and an NSMutableDictionary, then? Associated objects buy you nothing here: they make sense when you have a value which is, well, <i>associated</i> with another object. It makes no sense to associate singletons with NSApp.73a578542a129ea0fea16ecd76a97a63Sun, 04 Oct 2009 02:11:53 GMTLinan Wang - 2009-10-03 22:11:16http://www.mikeash.com/?page=pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html#commentsBy getting rid of the static global, it's one step towards the ruby's way to implement singleton. I'm sure it's possible to work out a helper class like this: <br /> <br />@implementation SingletonHelper <br /> <br />+ (id)initializeSingletonClass:(Class)kls onceT:(dispatch_once_t)pred; <br />{ <br />&nbsp;&nbsp;&nbsp;&nbsp;// Add the [kls sharedKls] message <br />&nbsp;&nbsp;&nbsp;&nbsp;NSString *msg_name = [NSString stringWithFormat:@"shared%@", NSStringFromClass(kls)]; <br />&nbsp;&nbsp;&nbsp;&nbsp;SEL sel = NSSelectorFromString(msg_name); <br />&nbsp;&nbsp;&nbsp;&nbsp;Method m = class_getClassMethod(SingletonHelper, @selector(getSharedInstance)); <br />&nbsp;&nbsp;&nbsp;&nbsp;class_addMethod(kls, sel, method_getImplementation(m), "@@:"); <br />&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;// initialize the shared instance, and return <br />&nbsp;&nbsp;&nbsp;&nbsp;id ret; <br />&nbsp;&nbsp;&nbsp;&nbsp;dispatch_once(&amp;pred, ^{ <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret = [[[kls alloc] init] autorelease]; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;objc_setAssociatedObject(NSApp, sel, OBJC_ASSOCIATION_RETAIN); <br />&nbsp;&nbsp;&nbsp;&nbsp;}); <br />&nbsp;&nbsp;&nbsp;&nbsp;return ret; <br />&nbsp;&nbsp;&nbsp;&nbsp; <br />} <br /> <br />+ (id)getSharedInstance; <br />{ <br />&nbsp;&nbsp;&nbsp;&nbsp;return objc_getAssociatedObject(NSApp, _cmd); <br />} <br /> <br />@end <br />(Codes are not tested yet.) <br /> <br />Then, to make a singleton class, all need to do is like this: <br />@interface ExampleSignleton : NSObject <br />{ <br />} <br />@end <br /> <br /> <br />@implementation ExampleSignleton <br />+ (void)initialize <br />{ <br />&nbsp;&nbsp;&nbsp;&nbsp;static dispatch_once_t pred; <br />&nbsp;&nbsp;&nbsp;&nbsp;[SingletonHelper initializeSingletonClass:[self class] onceT:pred]; <br />} <br />@end <br /> <br />For the problem of using @selector(sharedFoo) as the key, I think there is nothing stops me (an individual programer) to create my own conventions, and, if my conventions are consistent within the scope of a project, it'll be fine.fac2715c8d439708acbae17655f67b31Sat, 03 Oct 2009 22:11:16 GMTmikeash - 2009-10-03 13:07:47http://www.mikeash.com/?page=pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html#commentsCan you explain what makes this better? It looks slower, uglier, and more error prone (what if somebody else uses @selector(sharedFoo) as a key on NSApp too?) than just using a static global.70ead28339106f8cabdc607ceb71dcc8Sat, 03 Oct 2009 13:07:47 GMTLinan Wang - 2009-10-03 01:09:32http://www.mikeash.com/?page=pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html#commentsInstead of using: <br />static Foo *gSharedFoo; <br /> <br />I think it's a better to use the new associated object feature: <br /> <br />+(void)initialize{ <br />&nbsp;&nbsp;static dispatch_once_t pred; <br />&nbsp;&nbsp;Foo *foo; <br /> <br />&nbsp;&nbsp;&nbsp;dispatch_once(&amp;pred, ^{ <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foo = [[[self alloc] init] release]; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;objc_setAssociatedObject(NSApp, @selector(sharedFoo), OBJC_ASSOCIATION_RETAIN); <br />&nbsp;&nbsp;&nbsp;}); <br /> <br />&nbsp;&nbsp;&nbsp;return foo; <br />} <br /> <br />+(id)sharedFoo{ <br />&nbsp;&nbsp;&nbsp;return objc_getAssociatedObject(NSApp, _cmd); <br />}e179e8034d3d52deeb708aa480742aa3Sat, 03 Oct 2009 01:09:32 GMTmikeash - 2009-10-02 23:06:13http://www.mikeash.com/?page=pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html#comments<b>Brent Royal-Gordon:</b> I don't think I'd do this as an actual post, lacking experience in it, but here's the quickie summary. <br /> <br />If you're using garbage collection, then life is easy. Use an NSMapTable with weak objects. Wrap it in a lock if you need it to be thread safe. <br /> <br />Non-GC non-thread-safe is also fairly easy. Same NSMapTable setup, then have each cached object clear its own entry in -dealloc. <br /> <br />Non-GC thread-safe is a bit harder. You have to watch out for the case where one thread releases the last reference to a cached object, and then another thread tries to retrieve that reference before the object is actually removed from the NSMapTable. To avoid this, you'll probably want to implement your own reference counting mechanism (override retain/release) so that these are protected by the same lock that protects the NSMapTable. <br /> <br /><b>natevw:</b> I <i>think</i> that you also need an OSMemoryBarrier() before the return foo; for this to be 100% correct. (I think we discussed this before and I thought this was ok, but now I'm less certain.) And of course your singleton object needs to be able to tolerate multiple (unused) instances for a short period. <br /> <br /><b>ChristopherAtlan:</b> Yes, that will work fine as well, although it's a bit slower. I also don't like the fact that they don't support a context pointer to the function the way dispatch_once does. However, it's perfectly fine for this usage. <br /> <br />f24fc05e9f4382ed67d785cfa29f4523Fri, 02 Oct 2009 23:06:13 GMTChristopher Atlan - 2009-10-02 22:11:45http://www.mikeash.com/?page=pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html#commentsInstead of dispatch_once there is also the POSIX pthread_once (<a href="http://opengroup.org/onlinepubs/007908799/xsh/pthread_once.html">http://opengroup.org/onlinepubs/007908799/xsh/pthread_once.html</a>) out there. 02c2911e7f1c72c77b58bb648267316aFri, 02 Oct 2009 22:11:45 GMTnatevw - 2009-10-02 20:00:47http://www.mikeash.com/?page=pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html#commentsWhat about something like: <br /> <br />+ (id)sharedFoo { <br />&nbsp;&nbsp;&nbsp;&nbsp;static Foo* volatile foo = nil; <br />&nbsp;&nbsp;&nbsp;&nbsp;if (!foo) { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Foo* tmpFoo = [[self alloc] init]; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bool set = OSAtomicCompareAndSwapPtrBarrier(nil, tmpFoo, (void*volatile*)&amp;foo); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!set) [tmpFoo release]; <br />&nbsp;&nbsp;&nbsp;&nbsp;} <br />&nbsp;&nbsp;&nbsp;&nbsp;return foo; <br />} <br /> <br />It would do a bit of wasted work if the first few calls do happen simultaneously, but is this a good solution for pre-GCD code?710f8a13ee18fd5dd30e4e6c45b9d638Fri, 02 Oct 2009 20:00:47 GMTBrent Royal-Gordon - 2009-10-02 18:49:34http://www.mikeash.com/?page=pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html#commentsHi, Mike. Thanks for the series—it's quite informative. <br /> <br />I'd love to hear about uniquing objects—that is, ensuring that only a single object of a given class with (say) a given ID number is allocated in the application at a time. I've done this a few times, but I've never worked out how to allow them to be deallocated when they're no longer used—and there may be other tricks I don't know about.68f5e1e1f00742a6c991ce7a28d1521bFri, 02 Oct 2009 18:49:34 GMTSteven Degutis - 2009-10-02 17:50:45http://www.mikeash.com/?page=pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html#commentsMy take at Mike's challenge of an automatic singleton superclass... <a href="http://gist.github.com/199935">http://gist.github.com/199935</a> -- (my only gripe is the inconsistency in the accessor's name, compared to common Cocoa names like defaultCenter and sharedManager, etc.) <br /> <br />Jeff: <br /> <br />Not that I was asked, but I'd say the difference between singletons and a class with only class methods, are the instance variables. You would have to create a lot of static vars in your class, to act as ivars, and that just feels weird... not to mention, those pseudo-ivars aren't going to work well with things like KVC/KVO and @properties, and won't be accessible from within subclasses either, among other things.cf97e362702498c4b45f6951ef94a5b9Fri, 02 Oct 2009 17:50:45 GMTmikeash - 2009-10-02 17:40:05http://www.mikeash.com/?page=pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html#comments<b>Jeff Johnson:</b> I don't like using class objects directly for a couple of reasons. One is that using static globals instead of ivars is somewhat annoying and unclean. Another is that it locks you into the singleton-ness of the code much more strongly. A well designed singleton can support multiple instances with little work if it should become necessary later on, but moving a class-singleton to support multiple instances is much less fun. Finally, it occasionally makes sense to subclass a singleton (e.g. NSApplication or NSDocumentController) and this doesn't really work when using a class object for one. <br /> <br />Overall I don't think it makes a big difference, but real instances are somewhat cleaner and not much harder.6f89096ec794ea5de900b5541254099fFri, 02 Oct 2009 17:40:05 GMTmikeash - 2009-10-02 17:32:10http://www.mikeash.com/?page=pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html#comments<b>Georg:</b> Yes, it blocks until the initializer block has completed, that's pretty much the whole point of it. <br /> <br /><b>Steven Degutis:</b> I think I've seen such things around (cocoadev.com maybe) but don't recall. As for reentrancy in the shared getter, reassigning is a bad idea, due to the fact that init can return a different object. Better would be to simply refer to self in your initializer, since that's what you're really after anyway.497cf684974d5642293ebbca314849dbFri, 02 Oct 2009 17:32:10 GMTJeff Johnson - 2009-10-02 17:30:24http://www.mikeash.com/?page=pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html#commentsMike, Objective-C has built-in singletons, namely, class objects. :-) How do you feel about using classes as singletons? Obviously you wouldn't be able to create multiple instances, but if you never need to do that, why create a shared instance of a class rather than using the class itself?a6873549d9470e9b24875b49e8c96cdaFri, 02 Oct 2009 17:30:24 GMTSteven Degutis - 2009-10-02 17:26:10http://www.mikeash.com/?page=pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html#commentsMike: <br /> <br />I also wanted to point out that this code is generally not reentrant for the -init method. If the -init method calls the shared (or global) accessor, it will loop forever. The fix for this that I use is to assign the global variable as foo = [self alloc] first, then reassign and initialize it via foo = [foo init].0e3fc4ac0ae87c08b500c86c529ab092Fri, 02 Oct 2009 17:26:10 GMTSteven Degutis - 2009-10-02 17:16:46http://www.mikeash.com/?page=pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html#commentsGreat article, in great depth. Thanks Mike! Your mention of how singletons may not always be singletons reminds me of the Universe example: we think there's only one universe, but we may discover later that there's more, and rewrite our scientific books (ie, a huge pain). <br /> <br />Curiously, assuming that an automatic singleton superclass is feasible and safe for production code, have you ever written or seen one? It seems to me like the perfect addition to my general-purpose Cocoa framework. (Granted, it's likely to almost always be the wrong answer, but the implementation of it is just tricky enough that it's annoying to rewrite over and over.)4e06ea30c95f079823e4f898f6952c38Fri, 02 Oct 2009 17:16:46 GMTGeorg - 2009-10-02 17:01:00http://www.mikeash.com/?page=pyblog/friday-qa-2009-10-02-care-and-feeding-of-singletons.html#commentsDoes dispatch_once() block if the block is currently being executed?7b72b83375f614d51683114204b9b3ccFri, 02 Oct 2009 17:01:00 GMT