views:

67

answers:

3

Hi

So i have a uiviewcontroller. It has a property of an NSMutableArray with a nonatomic, retain property synthesized.

In the viewDidLoad I init it with the following, and also add a button to the nav bar.

test = [NSDictionary dictionaryWithObjectsAndKeys:
        [[SearchField alloc] initWithName:@"Subject" :Text], kSubjectKey, 
        [[SearchField alloc] initWithName:@"Source publication" :Text], kSourceKey,
        [[SearchField alloc] initWithName:@"Keyword" :Text], kKeywordKey,
        [[SearchField alloc] initWithName:@"Author" :Text], kAuthorKey,
        [[SearchField alloc] initWithName:@"Color" :Bool], kColorKey,
        nil ];

NSLog([NSString stringWithFormat:@"lol %d", [test count]]);

The first log, when running through the debugger runs fine. However, I have tied the following code to the button:

-(void)search:(id)sender{

    NSLog([NSString stringWithFormat:@"lol %d", [test count]]);

When this code executes the log line crashes with exc bad access. Nothing is happening to the NSDictionary between the viewDidLoad and the button press, so why is this happening? And more importantly, how do I fix it? :)

Cheers

Edit I thought maybe it was my SearchField class was doing things, so i replaced them with simple strings, the problem still occurs.

+3  A: 

You're directly accessing the member variable - you need to go through the accessor - ie:

self.test = [NSDictionary dictionaryWithObje ...

This will make sure your object retains the dictionary.

JosephH
+1  A: 

The dictionary you're creating is autoreleased. You're using a convenience method (dictionaryWithObjectsAndKeys:) which returns a new autoreleased object.

The autoreleased object is being released (and deallocated) some time after its creation, which is why it's crashing later in the program.

You need to retain the returned dictionary, or create a new dictionary using the alloc/init method.

Either way, you need to remember to release the dictionary when you're done with it.

You should read up on the basic memory management rules and conventions for Objective-C.

Jasarien
+3  A: 
  1. Make sure test is a class variable, by setting it up as a property of your view controller's header:

    @property (nonatomic, retain) NSDictionary *test;

  2. Release it in your view controller's -dealloc method:

    [test release], test = nil;

  3. Set its value as follows:

    self.test = [NSDictionary dictionaryWithObjectsAndKeys:...];

  4. Access its count property as follows:

    NSLog(@"Count: %u", test.count);

    Or:

    NSLog(@"Count: %u", [test count]);

    Note that -count returns an unsigned integer, so you should use %u to format its value.

Alex Reynolds