为什么更改字典中包含的可变数组不需要更新字典?

NRR*_*NRR 3 collections cocoa-touch objective-c

我正在尝试CS193P课程(Objective-C)的一段代码.我注意到编译器的工作方式.一个NSMutableArray被叫photos被添加到NSMutableDictionary,photosByPhotographer.后来,在photos没有任何改变的情况下进行了更改photosByPhotographer.当我记录时photosByPhotographer,更改自动应用于它,它不需要任何额外的代码行!

我想知道编译器如何使这个工作?有什么材料可供阅读吗?

代码如下:

- (void)updatePhotosByPhotographer
{
    NSMutableDictionary *photosByPhotographer = [NSMutableDictionary dictionary];
    for (NSDictionary *photo in self.photos) {
        NSString *photographer = [photo objectForKey:FLICKR_PHOTO_OWNER];
        NSMutableArray *photos = [photosByPhotographer objectForKey:photographer];
        if (!photos) {
            photos = [NSMutableArray array];
            [photosByPhotographer setObject:photos forKey:photographer];
            NSLog(@"photosByPhotographer in if: %@", photosByPhotographer);
        }
        [photos addObject:photo];
        NSLog(@"photosByPhotographer after if: %@", photosByPhotographer);
    }
    self.photosByPhotographer = photosByPhotographer;
}
Run Code Online (Sandbox Code Playgroud)

NSLog()结果如下:

2012-07-20 20:05:57.618 Shutterbug[453:f803] photosByPhotographer in if: {
Dowbiggin =     (
);
}

2012-07-20 20:05:57.620 Shutterbug[453:f803] photosByPhotographer after if: {
Dowbiggin =     (
            {
        accuracy = 16;
        context = 0;
        dateupload = 1342836026;
        description =             {
            "_content" = "";
        };
        farm = 9;
        "geo_is_contact" = 0;
        "geo_is_family" = 0;
        "geo_is_friend" = 0;
        "geo_is_public" = 1;
        id = 7612787270;
        isfamily = 0;
        isfriend = 0;
        ispublic = 1;
        latitude = "37.307085";
        longitude = "-121.900395";
        originalformat = jpg;
        originalsecret = 052e70d412;
        owner = "22751315@N05";
        ownername = Dowbiggin;
        "place_id" = cils8sJUV7MeXHwt9A;
        secret = 4437007c99;
        server = 8161;
        tags = "square squareformat iphoneography instagramapp uploaded:by=instagram foursquare:venue=49f13597f964a5209c691fe3";
        title = "My little goofball";
        woeid = 55971033;
    }
);
}
Run Code Online (Sandbox Code Playgroud)

v1A*_*xvw 5

那是因为在Cocoa中,您正在使用对象并通过引用传递.

想象一下这段代码:

NSMutableArray *a, *b;

a  = [NSMutableArray new];
[a addObject:@"A"]; // a contains @"A"
b = a; // b is assigned to the same object
[b addObject:@"B"]; // a and b contain @"A", @"B"

NSLog(@"a = %p and b = %p", a, b); // same values
Run Code Online (Sandbox Code Playgroud)

变量ab 指向同一个对象.您还可以通过比较指针值来查看.

但是,如果我们执行以下操作:

NSMutableArray *a, *b;

a  = [NSMutableArray new];
[a addObject:@"A"]; // a contains @"A"
b = [[a mutableCopy] autorelease]; // b is assigned to a COPY of the object
[b addObject:@"B"]; // b contains @"A", @"B", while a still contains @"A"

NSLog(@"a = %p and b = %p", a, b); // NOT the same values
Run Code Online (Sandbox Code Playgroud)

b被分配给a(不是原始)的副本,因此b指向另一个对象.您可以通过比较对象的地址来检查.