Re: Mutability
Re: Mutability
- Subject: Re: Mutability
- From: "John C. Randolph" <email@hidden>
- Date: Wed, 21 Nov 2001 11:34:07 -0800
Let me just toss something else into this discussion:
@interface MiscSingletonEnumerator : NSEnumerator
/*"The purpose of this class os to allow single objects to behave like
collections (NSArray, NSSet, etc.), without the trouble of creating an
array instance. The one-shot enumerator will act like any other
enumerator, returning the object it points to, and then returning nil."*/
{
id target; /*"The object that this enumerator will return."*/
}
+ (NSEnumerator *) enumeratorForObject: anObject;
- initTarget:(id) aTarget;
- nextObject;
@end
@interface NSObject (MiscSingletonEnumerator)
- (NSEnumerator *)objectEnumerator;
- (NSEnumerator *)reverseObjectEnumerator;
@end
@implementation MiscSingletonEnumerator
+ (NSEnumerator *) enumeratorForObject: anObject
/*"This is the only method you really need to obtain one-shot
enumerators. The enumerator you get is autoreleased."*/
{ return [[[self alloc] initTarget:anObject] autorelease]; }
- initTarget:(id) aTarget
/*"Initializes the receiver to point to aTarget"*/
{
target = aTarget;
return self;
}
- nextObject
/*"This method will return the target the first time it is called, and
will return nil every time after that."*/
{
id
result = target;
target = nil; // clear the ivar.
return result;
}
@end
@implementation NSObject (MiscSingletonEnumerator)
- (NSEnumerator *)objectEnumerator
/*"Creates and returns a one-shot enumerator which will return the
receiver once."*/
{ return [MiscSingletonEnumerator enumeratorForObject:self]; }
- (NSEnumerator *) reverseObjectEnumerator
/*"This just calls through to [NSObject objectEnumerator]. Since
there's only one object to enumerate, it's the same difference."*/
{ return [self objectEnumerator]; }
@end
Since I implemented this category of NSObject, everything in my code is
capable of behaving as a collection of a single object. Now, suppose I
have code that expects its parameter to be an NSArray, and I pass it a
single object instead. I contend that if the method in question demands
that its parameter must *be* an array, instead of demanding that it can
*act as* an array, then it's being needlessly particular.
So, rather than:
- someMethodThatWantsAnArray:(NSArray *) anArray;
I would strongly prefer (and advocate)
- someMethodThatWantsAnArray:(id <ArrayProtocol>) anArray;
This in fact, is a big part of why NeXT added protocols to Obj-C in the
first place. You shouldn't care what an object *is*, you should care if
it can do what you need it to do.
-jcr
I almost had a psychic girlfriend, but she left me before we met. --
Steven Wright