views:

218

answers:

4

IET ANOTHER EDIT (to increase strangeness) EDITED to show the relevant part of the code

Hi. There's a strange problem with an NSMutableArray which I'm just not understanding...

Explaining:

I have a NSMutableArray, defined as a property (nonatomic, retain), synthesized, and initialized with 29 elements.

realSectionNames = [[NSMutableArray alloc] initWithCapacity:29];

After the initialization, I can insert elements as I wish and everything seems to be working fine.

While I'm running the application, however, if I insert a new element in the array, I can print the array in the function where I inserted the element, and everything seems ok.

However, when I select a row in the table, and I need to read that array, my application crashes. In fact, it cannot even print the array anymore.

Is there any "magical and logical trick" everybody should know when using a NSMutableArray that a beginner like myself can be missing?

Thanks a lot.

I declare my array as

realSectionNames = [[NSMutableArray alloc] initWithCapacity:29];

I insert objects in my array with

[realSectionNames addObject:[category categoryFirstLetter]];

although I know i can also insert it with

[realSectionNames insertObject:[category categoryFirstLetter] atIndex:i];

where the "i" is the first non-occupied position.

After the insertion, I reload the data of my tableView. Printing the array before or after reloading the data shows it has the desired information.

After that, selecting a row at the table makes the application crash. This realSectionNames is used in several UITableViewDelegate functions, but for the case it doesn't matter. What truly matters is that printing the array in the beginning of the didSelectRowAtIndexPath function crashes everything (and of course, doesn't print anything). I'm pretty sure it's in that line, for printing anything he line before works (example):

NSLog(@"Anything");
NSLog(@"%@", realSectionNames);

gives the output:

2010-03-24 15:16:04.146 myApplicationExperience[3527:207] Anything

[Session started at 2010-03-24 15:16:04 +0000.] GNU gdb 6.3.50-20050815 (Apple version gdb-967) (Tue Jul 14 02:11:58 UTC 2009) Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-apple-darwin".sharedlibrary apply-load-rules all Attaching to process 3527.

Still not understanding what kind of stupidity I've done this time... maybe it's not too late to follow the career of brain surgeon?

following an answer, i printed

NSLog(@"self=%x", self); 
NSLog(@"self=%@", self); 
NSLog(@"realSectionNames=%x", realSectionNames); 

gives the exact same results in every function (from delegate or not).

NSLog(@"realSections = %@", realSectionNames); 

prints well in my viewWillAppear, in the didSelectRowAtIndexPath, and crashes in viewForHeaderInSection. No threading, by the way...

So, without knowing what to do, I'm trying "things"... I changed all references of realSectionNames to self.realSectionNames

printing in the viewForHeaderInSection gives the following problem:

2010-03-24 16:01:44.067 myApplication[4104:207] numberOfSectionsInTableView result -> 1
2010-03-24 16:01:44.068 myApplication[4104:207] viewForHeaderAtSection
2010-03-24 16:01:44.068 myApplication[4104:207] self=3d13470
2010-03-24 16:01:44.068 myApplication[4104:207] self=<RootViewController: 0x3d13470>
2010-03-24 16:01:44.069 myApplication[4104:207] self.realSectionNames=3b12830
2010-03-24 16:01:44.070 myApplication[4104:207] realSections = (
    <__NSArrayReverseEnumerator: 0x3b50500>
)
2010-03-24 16:01:44.070 myApplication[4104:207] *** -[__NSArrayReverseEnumerator length]: unrecognized selector sent to instance 0x3b50500
2010-03-24 16:01:44.071 myApplication[4104:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayReverseEnumerator length]: unrecognized selector sent to instance 0x3b50500'
2010-03-24 16:01:44.072 myApplication[4104:207] Stack: (
    31073371,
    2572170505,
    31455291,
    31024758,
    30877378,
    276908,
    26404,
    3227182,
    4544033,
    4551926,
    4550923,
    3267462,
    3207973,
    3249408,
    25927,
    3222086,
    3205252,
    459178,
    30857920,
    30854216,
    39163413,
    39163610,
    2949039
)

What is a NSArrayReverseEnumerator??? And why is it being mean to me???

+1  A: 

When an application crashes, the Xcode Console will report the error that caused the application to crash. You will want to edit your question to include this error message, along with relevant source code, as this will help others answer your question.

I suspect your selected table row is trying to point to an index in the array, which does not exist. If so, you're trying to reference a part of the array that does not exist. This causes your application to throw an exception and quit.

Remember that an NSMutableArray can be initialized to a certain capacity, but until items are inserted, it does not actually hold any objects. The -initWithCapacity: method only sets aside a certain amount of memory, but there are no placeholders or nil entries for 1 through n indices.

Alex Reynolds
A: 

1) Could we know the error message ? and the relevant part of the code ?

2) Here is the proper way to declare your array :

self.realSectionNames = [[NSMutableArray arrayWithCapacity:29];
chacha
There's nothing wrong with using alloc and init to create an NSMutableArray, especially if you need to keep it around past when the autorelease pool is drained.
Jeff Kelley
So why synthesizing it if you don't use the setter ?
chacha
A: 

I suspect your TableView's delegate isn't hooked up correctly, or is connected to an invalid object. Are any of your other delegate methods working? Try putting these at the top of didSelectRowAtIndexPath to check the pointer values:

NSLog(@"self=%x", self);
NSLog(@"self=%@", self);
NSLog(@"realSectionNames=%x", realSectionNames);
codewarrior
NSLog(@"self=%x", self); NSLog(@"self=%@", self); NSLog(@"realSectionNames=%x", realSectionNames); gives the exact same result anywhere. NSLog(@"realSections = %@", realSectionNames); prints well in my viewWillAppear, in the didSelectRowAtIndexPath, and crashes in viewForHeaderInSection.
camilo
+1  A: 

Note to everybody (and specially to self)...

I'm a dumb, dumb boy.

I was releasing an element which I inserted in the array.

Sorry for the questions, thanks for the answers...

camilo