• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: problem with subclassing a cluster class
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


  • Follow-Ups:
    • Re: problem with subclassing a cluster class
      • From: Greg Herlihy <email@hidden>
References: 
 >Re: problem with subclassing a cluster class (From: Greg Herlihy <email@hidden>)

  • Prev by Date: NSOpenPanel icon view
  • Next by Date: Re: Using a custom NSCell for NSButton created in IB
  • Previous by thread: Re: problem with subclassing a cluster class
  • Next by thread: Re: problem with subclassing a cluster class
  • Index(es):
    • Date
    • Thread