views:

64

answers:

2

I want to use NSMutableDictionary to cache some data i will use later. My custom object is following:

@interface MyData : NSObject {
    NSRange range;
    NSMutableArray *values;
}
@property (nonatomic, retain) NSMutableArray *values;

and implement:

- (id)init {
    if (self = [super init]) {
        values = [[NSMutableArray alloc] init];
    }

    return self;
}

and when i wanna cache it, i use it like this:

NSMutableDictionary *cache = [[NSMutableDictionary alloc] init];
NSString *key = @"KEY";
MyData *data = [[MyData alloc] init];
// save some data into data
[data.values addObject:"DATA1"];
[data.values addObject:"DATA2"];
//... ...
[cache setObject:data forKey:key];

My questions is the count of cache.values is zero when i retrieve this object later as follow:

[cache objectForKey:@"KEY"];

i can retrieve "data" and the object's memory address is the same as the address when i put it into cache. what's wrong? i need some kind guys help, any info is helpful. thanks

A: 

As Carl Norum pointed out, you're passing C strings to addObject:. addObject:, as its name suggests, requires a pointer to a Cocoa object; a C string is a pointer to characters. You need to pass NSString objects there; for literal strings, this simply requires prefixing them with @: "Fred" is a constant C string, whereas @"Fred" is a constant NSString object.

Is cache an instance variable? It looks like it's not; it appears to be a local variable, which means you're creating a new dictionary object every time. That's why there's nothing you've added previously (to previous dictionaries) in the new one. It also means you're leaking those previous dictionaries, since you're not releasing them (not in the code you showed, anyway).

Make cache an instance variable and only create the dictionary when you don't already have one (i.e., when cache == nil). Creating the dictionary in your init method is one good way. And make sure you manage its lifetime appropriately, so you don't leak and/or crash.

Peter Hosey
A: 

First of all your objects your adding don't look right it should have an @ before the string. Like @"DATA1"

Second when you add an object to a dictionary or an array it does not make an actual copy of it. It just creates a pointer to it so if those objects are destroyed or moved somewhere also they are also gone out of your dictionary. A better way to make a cache of your values would be to copy the objects like so:

MyData* cache = [[MyData alloc] init];

for (int i = 0; i < [data.values count]; i ++){{
    [cache.values addObject:[NSString stringWithString:[data.values objectAtIndex:i]]];
}

Don't use a dictionary in this situation.

Justin Meiners
Yes, thank u for your help, i didn't protect the var with updating later. After your answer, i'm clear about pointer. so thank u again.