tags:

views:

35

answers:

2

Is it possible to use the class methods of some NSObject I've made to controls all existing instances?

I want a delegate class to be able to send messages to the Object's class methods which can then react appropriately with everything out there.

+1  A: 

Not without using some collection of the objects. The simplest way to do it would be to store the objects in an array and send them all a message when you want something to happen. Specifically:

static NSMutableArray *allObjects = nil;
+ (void) initialize {
    if (!allObjects) {
        allObjects = [NSMutableArray new];
    }
}
- (id) init {
    if (self = [super init]) {
        //Each object gets held in an array
        [allObjects addObject:self];
    }
    return self;
}
+ (void) doSomethingToEveryObject {
    [allObjects makeObjectsPerformSelector:@selector(doSomethingToThisObject)];
}
- (void) doSomethingToThisObject {
    NSLog(@"Did something to %@",self];
}
- (void) release {
    [super release];
    //When the retain count reaches 1, then all external references have disappeared,
    //and the only remaining reference is in the objects array.
    if (self.retainCount == 1) {
      [allObjects removeObject:self];
    }
}
Ed Marty
While this would work, overriding a method like `release` always strikes me as fishy.
Squeegy
It's perfectly fine to do as long as you know what you're doing. You could alternatively create your own array class that does not retain its members if you don't want to override the release method. Seems like a lot of work to avoid a three-line function.
Ed Marty
No. It's horrible. It might be justified if NSPointerArray (an Objective-C array that can be configured not to retain its elements) didn't exist. http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSPointerArray_Class/Introduction/Introduction.html#//apple_ref/occ/cl/NSPointerArray
JeremyP
Thanks Ed, This looks like the approach I was thinking of conceptually, but I should use an NSPointerArray instead of NSMutableArray?
spadict
Sorry, I'm an iPhone developer; I was unaware of NSPointerArray, because it doesn't exist in the iPhone SDK. Makes sense to use that instead.
Ed Marty
+1  A: 

Sure. Just have all the objects register for notifications when they're created. For example:

- (id)init {
    self = [super init];
    if (!self) return nil;

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(announceYourself:)
                                                 name:@"MYCLASS_ANNOUNCE"
                                               object:nil];
    return self;
}

+ (void)identifyInstances {
    [[NSNotificationCenter defaultCenter] postNotificationName:@"MYCLASS_ANNOUNCE" object:self];
}

- (void)announceYourself:(id)notification {
    NSLog(@"Instance %p reporting in!", self);
}

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self]; // VERY IMPORTANT -- IT WILL CRASH WITHOUT THIS
    [super dealloc];
}
Chuck