This is UniqueInstance.m in view mode; [Download] [Up]
/****************************************************************************** .../UniqueInstance.m Copyright Michael T. H. Scott, 1995. UniqueInstance is a class which can have only one instance. Alloc, copy and free return error. NOTE InterfaceBuilder uses _zoneAlloc() to create an instance of a custom object. It does not call +alloc. By overriding _zoneAlloc() for classes which respond to +uniqueInstance we guarantee that only one instance is ever allocated. It is necessary to remember that if multiple instances of a UniqueInstance subclass are included in an application's nib files then -init will be multiply called on that instance. ******************************************************************************/ #import "UniqueInstance.h" #import <objc/objc-runtime.h> static id uniqueInstances = nil; static id initialized = nil; static const char *msg = "does not %s.\n"; static id (*runtimeZoneAlloc)(); static id uniqueInstanceZoneAlloc(Class aClass, unsigned int indexedIvarBytes, NXZone *zone); @implementation UniqueInstance /*----------------------------------------------------------------------------- Initializes the HashTable which will contain the unique instance for each UniqueInstance subclass. -----------------------------------------------------------------------------*/ + initialize { if ( self == [UniqueInstance class] ) { uniqueInstances = [[HashTable allocFromZone: [self zone]] initKeyDesc: "@" valueDesc: "@"]; initialized = [[List allocFromZone: [self zone]] init]; runtimeZoneAlloc = _zoneAlloc; _zoneAlloc = uniqueInstanceZoneAlloc; } return self; } /*----------------------------------------------------------------------------- Returns the unique instance of the receiving class. -----------------------------------------------------------------------------*/ + uniqueInstance { const void *key = (const void *)self; id uniqueInstance = (id)[uniqueInstances valueForKey: key]; if ( !uniqueInstance ) { uniqueInstance = runtimeZoneAlloc(self, 0U, [self zone]); [uniqueInstances insertKey: key value: (void *)uniqueInstance]; [uniqueInstance init]; [initialized addObject: uniqueInstance]; } return uniqueInstance; } /*----------------------------------------------------------------------------- Reimplemented to return error. -----------------------------------------------------------------------------*/ + alloc { return [self error: msg, sel_getName(_cmd)]; } /*----------------------------------------------------------------------------- Returns whether the receiver is uninitialized. -----------------------------------------------------------------------------*/ - (BOOL)uninitialized { return [initialized indexOf: self] == NX_NOT_IN_LIST; } /*----------------------------------------------------------------------------- Designated initializer. -----------------------------------------------------------------------------*/ - init { if ( [self uninitialized] ) [super init]; return self; } /*----------------------------------------------------------------------------- Reimplemented to return error. -----------------------------------------------------------------------------*/ - copyFromZone: (NXZone *)aZone { return [self error: msg, sel_getName(_cmd)]; } /*----------------------------------------------------------------------------- Reimplemented to return error. -----------------------------------------------------------------------------*/ - free { return [self error: msg, sel_getName(_cmd)]; } @end /*----------------------------------------------------------------------------- Overrides _zoneAlloc to return the unique instance of a UniqueInstance subclasses. -----------------------------------------------------------------------------*/ static id uniqueInstanceZoneAlloc(Class aClass, unsigned int indexedIvarBytes, NXZone *zone) { if ( [aClass respondsTo: @selector(uniqueInstance)] ) { return [aClass uniqueInstance]; } return runtimeZoneAlloc(aClass, indexedIvarBytes, zone); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.