Cake
Cake

Reputation: 109

NSMutableDictionary returning (null) for valid key/forget its values?

Ok. I have a class "Game", which creates an instance of my class "Board", and tests it.

The "Board" class has a dictionary, which seems to somehow not being able to keep it's values(?) Tried to strap down the code to the minimal:

The Game class:

@interface Game : UIViewController{
    Board *board;
}
-(void)testAgain; 

@implementation Game
-(void)setup{
    board = [Board alloc]createBoard];
    [board test]; //returns right value
    [self testAgain]; //returns (null), see output below
}
-(void)testAgain{
    [board test];
}

-(void)didLoad{
    [self setup];
}

The Board Class:

@interface Board : NSObject{
@property(nonatomic, retain) NSMutableDictionary *dict;

-(Board *)createBoard;
-(void)test;

@implementation Board
@synthesize dict;

-(Board *)createBoard{

    dict = [[NSMutableDictionary alloc]init];

    [dict setObject:@"foo1" forKey:@"1"];
    [dict setObject:@"foo2" forKey:@"2"];
    [dict setObject:@"foo3" forKey:@"3"];
    [dict setObject:@"foo4" forKey:@"4"];
    [dict setObject:@"foo5" forKey:@"5"];

    return self;
}

-(void)test{
    NSLog(@"Test return: %@", [dict objectForKey:@"4"]);
}

The following output:

2012-06-23 01:05:28.614 Game[21430:207] Test return: foo4
2012-06-23 01:05:32.539 Game[21430:207] Test return: (null)

In advance, thanks for any help!

Upvotes: 2

Views: 1394

Answers (2)

@implementation Game
-(void)setup{
    board = [[[Board alloc] init] createBoard];
    [board test]; //returns right value
    [self testAgain]; //returns (null), see output below
}

The creation pattern you are using is outside every convention in Objective-C. You should either use [Board new], [[Board alloc] init|With...|] or [Board board|With...|].

-(Board *)createBoard {

    self.dict = [[NSMutableDictionary alloc]init];

    [dict setObject:@"foo1" forKey:@"1"];
    [dict setObject:@"foo2" forKey:@"2"];
    [dict setObject:@"foo3" forKey:@"3"];
    [dict setObject:@"foo4" forKey:@"4"];
    [dict setObject:@"foo5" forKey:@"5"];
}

Lets see if your code works better with the missing init reinstalled where it belongs and that little missing self. .

Upvotes: 1

MCKapur
MCKapur

Reputation: 9157

First of all you are not correctly initializing the Board object using createBoard. You are not even returning a Board object in that method. Try modifying that method to something like this:

-(id)initWithCreatedBoard {

self = [super init];


if (self) { 

dict = [[NSMutableDictionary alloc]init];

[dict setObject:@"foo1" forKey:@"1"];
[dict setObject:@"foo2" forKey:@"2"];
[dict setObject:@"foo3" forKey:@"3"];
[dict setObject:@"foo4" forKey:@"4"];
[dict setObject:@"foo5" forKey:@"5"];

[dict retain];

}

return self;

}

You also might want to retain dict. Because they are probably getting deallocated.

Also, are you using ARC?

Another thing, instead of having two method testAgain and test. Just call test twice:

for (int i = 0; i <= 2; i++) {

[self test];

}

Just better structure, thats it. Please feedback your results!

Upvotes: 0

Related Questions