views:

2166

answers:

2

I'm a total noob to iPhone programming, and I've run into an exception being thrown that I just can't wrap my head around.

Background: The error is happening in a custom subview, and occurs immediately upon loading the program. I'm getting an exception thrown in the overridden drawRect method. The code throwing the error follows:

- (void)drawRect:(CGRect)rect{
    NSNumber *points = [NSNumber numberWithInt: star.numberOfPoints];
    //HERE. Doesn't recognize selector?!
    CGPathRef t = (CGPathRef)[starPaths objectForKey:points];
 /*snip*/

starPaths is initialized in awakeFromNib as an NSMutableDictionary with capacity 1.

The exception that's getting thrown is -[NSObject doesNotRecognizeSelector:]

starPaths is declared in the header file for the view as

    NSMutableDictionary *starPaths;

and is initialized as

- (void)awakeFromNib{
    starPaths = [NSMutableDictionary dictionaryWithCapacity: 1];
}

Finally, I haven't been able to get to a point in the code where I successfully add elements to the dictionary, since the code to add an entry relies on receiving a nil response from the dictionary to know that the that specific entry needs to be built.

Any suggestions? Any other information I should provide? Any help at all would be appreciated, I feel like I'm missing something obvious, but I've been bashing my head against this all day with no luck.

+3  A: 

If you do not retain the starPaths variable or explicitly allocate it yourself with [[NSMutableDictionary alloc] initWithCapacity:1] then it will be automatically released on the next iteration of the run loop.

You need to do

starPaths = [[NSMutableDictionary dictionaryWithCapacity:1] retain];

Or

starPaths = [[NSMutableDictionary alloc] initWithCapacity:1];

Just make sure to release it when you no longer need it.

dreamlax
Even better, just use a setter anytime you want to set an instance variable. This keeps your code consistent and puts the burden of memory management all on one method.
Chuck
That would be better indeed.
dreamlax
Aha! I didn't realize that the dictionary would be deallocated before it hit that point. Retaining it solved the problem. Thanks!
Zxaos
+1  A: 

A few things to check:

  • Is starPaths declared as an NSMutableDictionary* instance variable? You mention that it is initialized. Did you use the dictionaryWithCapacity method (which returns an auto-release object) or initWithCapacity (which needs to be explicitly retained). To be safe, you may want to retain it and release it when done.

  • Double-check to make sure the header files are properly included so the declaration of starPaths is included in implementation files that make use of it.

  • Generally speaking if you're getting mystery errors it has to do with corrupted memory. Try putting a breakpoint on the first line of the drawRect method and do a "po starPaths" in the debugger console window to see what's in it and what type of object the runtime thinks it is.

Ramin