Re: observing dealloc
Re: observing dealloc
- Subject: Re: observing dealloc
- From: Ken Tozier <email@hidden>
- Date: Mon, 28 May 2007 17:08:34 -0400
Well the solution was a bit more involved than I was expecting, but
if used as a base class for custom classes, it offers a standardized
way to add globals to any class. It handles subclass globals by
creating separate dictionaries for them and releases these
dictionaries when all instances of a class have been released.
One thing I'm not sure about is how this base class would behave in a
threaded environment. Anyone see any thread-related gotchas in the
following code?
- Ken
@implementation BaseObject
NSMutableDictionary *gGlobals = nil;
NSMutableDictionary *gCounters = nil;
+ (void) initialize
{
if (gGlobals == nil)
{
gGlobals = [[NSMutableDictionary alloc] init];
gCounters = [[NSMutableDictionary alloc] init];
}
}
- (id) init
{
self = [super init];
{
NSString *className = NSStringFromClass([self class]);
NSNumber *instanceCounter = [gCounters objectForKey: className];
int counter = (instanceCounter == nil) ? 0 :
[instanceCounter intValue] ;
counter++;
[gCounters setObject: [NSNumber numberWithInt: counter
forKey: className];
}
}
- (void) dealloc
{
NSString *className = NSStringFromClass([self class]);
NSNumber *instanceCounter = [gCounters objectForKey: className];
int counter = [instanceCounter intValue] ;
counter--;
if (counter == 0)
{
// no more objects of this class
// delete its counter and globals
[gCounters deleteObjectForKey: className];
[gGlobals deleteObjectForKey: className];
}
// if gCounters is empty, there are no more instances
// of any type so release gGlobals and gCounters
if ([gCounters count] == 0)
{
[gCounters release];
[gGlobals release];
}
[super dealloc];
}
+ (BOOL) globalsInitialized
{
NSString *className = NSStringFromClass([self class]);
return ([gGlobals objectForKey: className] == nil) ? NO : YES ;
}
+ (void) setGlobal:(id) inObj
forKey:(NSString *) inKey
{
NSString *className = NSStringFromClass([self class]);
NSMutableDictionary *classGlobals = [gGlobals objectForKey:
className];
if (classGlobals == nil)
{
classGlobals = [NSMutableDictionary dictionary];
[gGlobals setObject: classGlobals
forKey: className];
}
[classGlobals setObject: inObj
forKey: inKey];
}
+ (id) globalForKey:(NSString *) inKey
{
NSString *className = NSStringFromClass([self class]);
NSMutableDictionary *classGlobals = [gGlobals objectForKey:
className];
return (classGlobals == nil) ? nil : [classGlobals objectForKey:
inKey] ;
}
- (id) globalForKey:(NSString *) inKey
{
NSString *className = NSStringFromClass([self class]);
NSMutableDictionary *classGlobals = [gGlobals objectForKey:
className];
return (classGlobals == nil) ? nil : [classGlobals objectForKey:
inKey] ;
}
If MyObject is a subclass of BaseObject, it's globals can be set in
it's initialize method like this:
@implementation MyObject
- (void) initialize
{
if (![MyObject globalsInitialized])
{
[MyObject setGlobal: [NSColor colorWithDeviceRed: 1 green: 0 blue:
0 alpha: .5]
forKey: @"pink"];
[MyObject setGlobal: [NSColor colorWithDeviceRed: green: 1 blue: 0
alpha: .5]
forKey: @"lime"];
[MyObject setGlobal: [NSColor colorWithDeviceRed: green: 0 blue: 1
alpha: .5]
forKey: @"sky"];
}
}
And these globals can be fetched from instances by
[myObjectInstance globalForKey: @"lime];
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden