Re: problem with subclassing a cluster class
Re: problem with subclassing a cluster class
- Subject: Re: problem with subclassing a cluster class
- From: Ivan Kourtev <email@hidden>
- Date: Sun, 5 Mar 2006 17:26:11 -0500
Thanks, that helped. It took me a little while to wrap my brains
around it but I understand it now. I actually sort of came up with a
similar solution -- instead of the C arrays you suggested, I used an
NSMutableDictionary instance to put the arguments in, then
initWithDictionary for my embedded object. Works like a charm (code
at end).
--
ivan
On Mar 5, 2006, at 4:07 PM, Greg Herlihy wrote:
See comments below...
Since the dictionary is immutable, your routine must initialize it
with a
single call. The NSDictionary's entries cannot be added one at a
time like
your current code is doing. And that is the behavior causing the
problem.
Therefore I would recommend pre-allocating two reasonably-sized C
arrays,
one to hold the keys and the other to hold the values. Then I would
place
each key and value in the corresponding array as they are read in
(with the
usual precautions: being certain to use large enough arrays and
checking
that the current index is within a valid range).
Only after all the parameters have been processed in this way,
would I call
- (id)initWithObjects:(id *)objects forKeys:(id *)keys
count:(unsigned)count;
Passing pointers to the key and value arrays and how many items are in
either - for the count.
#import <Foundation/Foundation.h>
@interface MyDictionary : NSDictionary {
NSDictionary *embeddedDictionary;
}
- (id)init;
- (id)initWithDictionary:(NSDictionary *)otherDictionary;
+ (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...;
- (void)dealloc;
// Primitive methods of the abstract superclass
- (unsigned)count;
- (id)objectForKey:(id)aKey;
- (NSEnumerator *)keyEnumerator;
@end
@implementation MyDictionary
- (unsigned)count
{
assert( embeddedDictionary != nil );
return [embeddedDictionary count];
}
- (id)objectForKey:(id)aKey
{
assert( embeddedDictionary != nil );
return [embeddedDictionary objectForKey:aKey];
}
- (NSEnumerator *)keyEnumerator
{
assert( embeddedDictionary != nil );
return [embeddedDictionary keyEnumerator];
}
- (id)init
{
self = [super init];
if ( self ) {
embeddedDictionary = [[NSDictionary alloc] init];
}
return self;
}
- (id)initWithDictionary:(NSDictionary *)otherDictionary
{
self = [super init];
if ( self ) {
embeddedDictionary = [[NSDictionary alloc]
initWithDictionary:otherDictionary];
}
return self;
}
- (void)dealloc
{
[embeddedDictionary release];
[super dealloc];
}
+ (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...
{
// argument list empty: not much to do but return an empty
dictionary
if ( firstObject == nil ) {
return [[[self alloc] init] autorelease];
}
// arguments exist: create dictionary and insert keys and
objects from list
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
va_list argList;
id anObject, aKey;
va_start( argList, firstObject );
aKey = va_arg(argList, id);
NSLog( @"The first object from the argument list is %@",
firstObject );
NSLog( @"The next object from the argument list is %@", aKey );
if ( aKey == nil ) {
NSLog( @"Invalid arg list to %s", __PRETTY_FUNCTION__ );
assert( NO );
} else {
NSLog( @" Now inserting %@ for key %@", firstObject, aKey );
[dictionary setObject:firstObject forKey:aKey];
}
while ( ( anObject = va_arg( argList, id) ) != nil ) {
aKey = va_arg( argList, id);
if ( aKey == nil ) {
NSLog( @"Invalid arg list to %s", __PRETTY_FUNCTION__ );
assert( NO );
} else {
NSLog( @" Now inserting %@ for key %@", anObject, aKey );
[dictionary setObject:anObject forKey:aKey];
}
}
va_end( argList );
return [[[self alloc] initWithDictionary:dictionary] autorelease];
}
@end
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString *obj1 = [NSString stringWithString:@"myObject 1"];
NSString *key1 = [NSString stringWithString:@"myKey 1"];
NSString *obj2 = [NSString stringWithString:@"myObject 2"];
NSString *key2 = [NSString stringWithString:@"myKey 2"];
MyDictionary *dict = [MyDictionary
dictionaryWithObjectsAndKeys:obj1, key1, obj2, key2, nil];
NSLog( @"Created dictionary: %@", dict );
[pool release];
return 0;
}
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden