NSDictionaryのキーは変えられない(2) 値は変えられる

NSDictionaryのキーは変えられない - すぎゃーんメモの続き。
そういえばkeyにばっかり着目していて値の方を全然みてなかった。
とりあえずkeyと同様に中身を見てみることに。

#import <Foundation/Foundation.h>

int main(int argc, char *argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    NSString *key1 = @"hoge";
    NSString *key2 = @"fuga";
    NSString *key3 = @"piyo";
    NSArray *keys = [NSArray arrayWithObjects:key1, key2, key3, nil];

    NSMutableString *value1 = [NSMutableString stringWithString:@"foo"];
    NSMutableString *value2 = [NSMutableString stringWithString:@"bar"];
    NSMutableString *value3 = [NSMutableString stringWithString:@"baz"];
    NSArray *values = [NSArray arrayWithObjects:value1, value2, value3, nil];

    NSDictionary *dict = [NSDictionary dictionaryWithObjects:values forKeys:keys];
    NSArray *allkeys = [dict allKeys];

    for (id value in values) {
        NSLog(@"%p, %@, %@", value, value, [value className]);
    }
    NSLog(@"%p, %@", allkeys, [allkeys description]);
    for (id key in allkeys) {
        id value = [dict valueForKey:key];
        NSLog(@"%p, %@, %@", value, value, [value className]);
    }

    [pool release];
    
    return 0;
}

実行結果は

$ ./a.out
2008-12-04 06:42:07.846 a.out[1416:10b] 0x106080, foo, NSCFString
2008-12-04 06:42:07.847 a.out[1416:10b] 0x1060c0, bar, NSCFString
2008-12-04 06:42:07.849 a.out[1416:10b] 0x106100, baz, NSCFString
2008-12-04 06:42:07.849 a.out[1416:10b] 0x106920, (
    fuga,
    piyo,
    hoge
)
2008-12-04 06:42:07.849 a.out[1416:10b] 0x1060c0, bar, NSCFString
2008-12-04 06:42:07.850 a.out[1416:10b] 0x106100, baz, NSCFString
2008-12-04 06:42:07.850 a.out[1416:10b] 0x106080, foo, NSCFString

お!?こっちは全く同じインスタンスか!!
ということは元がNSMutableStringなら中身を変更できるのか…!?

...
    NSLog([dict description]);
    [[values objectAtIndex:1] appendString:@"++"];
    NSLog([dict description]);
...

とやってみると…

$ ./a.out
2008-12-04 06:42:07.850 a.out[1416:10b] {
    fuga = bar;
    hoge = foo;
    piyo = baz;
}
2008-12-04 06:42:07.854 a.out[1416:10b] {
    fuga = "bar++";
    hoge = foo;
    piyo = baz;
}

おー!!変更できる!!
そうか、値の方はインスタンスがそのまま格納されるから、他のインスタンスと入れ替わったりしていなければ内部表現が変わっても問題ないのか。