views:

41

answers:

2

Hello all! I'm new to objective-C. I want to use NSMutableArray to store some objects i will access later.

I've got the interface:

@interface ControlWheel : RotatableObject <LeverSubject>
{
 NSMutableArray *subjectArray_;
}
-(id) initWithCWDef: (ControlWheelDef*) def;
-(void) addSubject: (id) subject;
@end

Here is the implementation:

-(id) initWithCWDef:(ControlWheelDef *)def
{
    ...
    self = [super initWithDef:&rDef];
    if (self)
    {
        subjectArray_ = [NSMutableArray arrayWithCapacity:1];
    }
    return self;
}

-(void) addSubject:(id)subject
{
    [subjectArray_ addObject:subject];
}

-(void) angleChangeCallback
{
    unsigned int count = [subjectArray_ count];
    for (unsigned int i = 0; i < count; i++)
    {
        [[subjectArray_ objectAtIndex:i] onAngleChanged:angle_];
    }
}

The problem is in angleChangeCallback function. subjectArray_ is out of scope. What i'm doing wrong?

A: 

It doesn't look like you have angleChangeCallback defined in your interface at the top. I see addSubject and initWithCWDef but not him.

Grant Lammi
It's defined in a protocol
Andrew
even if method is not declared in @interface block it will be treated as a class method while its implementation in class @implementation/@end block
Vladimir
Oops. I should avoid posting early in the morning.
Grant Lammi
+4  A: 

arrayWithCapacity: returns an autoreleased array. You want [[NSMutableArray alloc] init];.

NSMutableArray grows as necessary, so arrayWithCapacity: isn't particularly useful, most of the time, unless you are going to fill it with a known, large number of objects.

Oh, and it's not gone out of scope; it's been collected by the autorelease pool.

Williham Totland
You could also just `retain` the array returned from `arrayWithCapacity`. Either way, don't forget to `release` it in your object's `dealloc` method.
walkytalky
@walkytalky: He could indeed `retain` the array, but there's another point here: `[NSMutableArray arrayWithCapacity:]` is basically equivalent to `[[[NSMutableArray alloc] initWithCapacity:] autorelease]`. And adding a retain to that would just be silly. Basically, he doesn't need the `WithCapacity:` bit, and should just get rid of it.
Williham Totland
@Williham An awful lot of convenience class methods in Cocoa are equivalent to an `alloc`/`initXXX`/`autorelease` sequence, and adding a `retain` is a fairly common idiom. Are you launching a campaign against that whole pattern? It's true the capacity is superfluous here, but the cost is insignificant in terms of both processing and code complexity. And what if the `1` were a placeholder value expected to be replaced later with some huge unknown quantity?
walkytalky
It's not. :P This is an array to hold a number of observers to a callback. The number of items is unknown and unbounded, the capacity has no function in this case. (At least, that is how I understand the code.) The problem here is that if someone looks over the code later, then including the capacity will lead them to utter a pointless "Huh? What's this doing here?"
Williham Totland