views:

87

answers:

3

I've got a simple object "post" that has two NSMutableArrays as properties. One is for "image" objects and the other is for "video" objects. At some point in the lifecycle of "post", I ask it for a dictionary representation of itself.

NSMutableDictionary *postDict = [post getDictionary];

-(NSMutableDictionary *)getDictionary{

    NSMutableArray *imgDictArry = [NSMutableArray arrayWithObjects:nil];
    NSMutableArray *movDictArry = [NSMutableArray arrayWithObjects:nil];

    for (int i = 0; i<self.images.count; i++) {
        NSMutableDictionary *imgDict = [[self.images objectAtIndex:i] getDictionary];
        [imgDictArry addObject:imgDict];
    }

    for (int i = 0; i<self.videos.count; i++) {
        NSMutableDictionary *movDict = [[self.videos objectAtIndex:i] getDictionary];
        [movDictArry addObject:movDict];
    }

    NSMutableDictionary *postDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                     [NSNumber numberWithBool:self.friendsOnly], @"IsFriendsOnly", 
                                     self.message, @"Message",
                                     self.shortText, @"ShortText",
                                     self.authorId, @"AuthorId",
                                     self.recipientId, @"RecipientId",
                                     self.language, @"Language",
                                     self.lat, @"Lat",
                                     self.lng, @"Lng",
                                     imgDictArry, @"Images",
                                     movDictArry, @"Videos",
                                     nil];

    return postDict;
}

As you can see, the "image" and "video" objects have their own methods for describing themselves as NSMutableDictionary objects.

-(NSMutableDictionary *)getDictionary{
    return [NSMutableDictionary dictionaryWithObjectsAndKeys:
            self.nativeURL, @"NativeURL",
            self.previewURL, @"PreviewURL",
            self.smallURL, @"SmallURL",
            self.thumbURL, @"ThumbURL",
            self.imageId, @"ImageId",
            self.width, @"Width",
            self.height, @"Height",
            nil];
}

I'm not getting any errors but my imgDictArry and movDictArry objects are turning out to be NULL after I've set them on the postDict object. If I log them to the console just before this moment, I can see the dictionary data. But the other classes requesting this object is getting null for those properties.

+3  A: 

Perhaps one of your functions such as self.shortText (or self.lat...) is returning nil, in which case dictionaryWithObjectsAndKeys isn't what you expect it to be: it's truncated to the first function that returns nil...

Zoran Simic
Also, all of the objects you pass to `dictionaryWithObjectsAndKeys:` must be *objects*; passing numeric values will either cause this problem (if 0) or almost-certainly crash (if not 0). You can even get both, if the value is smaller than a pointer (`dictionaryWithObjectsAndKeys:` will consume a pointer's worth no matter what, not realizing that you didn't pass one).
Peter Hosey
Yes, i think that's the most probable cause of this issue.
JeremyP
A: 

Since you're using class-methods to create your arrays and dictionairies (which return autoreleased objects), you need to retain them to prevent them from beeing deallocated. that could be the problem.



    NSMutableArray *imgDictArry = [[NSMutableArray arrayWithObjects:nil] retain];
    NSMutableArray *movDictArry = [[NSMutableArray arrayWithObjects:nil] retain];


and



       NSMutableDictionary *postDict = [[NSMutableDictionary dictionaryWithObjectsAndKeys:
                                     [NSNumber numberWithBool:self.friendsOnly], @"IsFriendsOnly", 
                                     self.message, @"Message",
                                     self.shortText, @"ShortText",
                                     self.authorId, @"AuthorId",
                                     self.recipientId, @"RecipientId",
                                     self.language, @"Language",
                                     self.lat, @"Lat",
                                     self.lng, @"Lng",
                                     imgDictArry, @"Images",
                                     movDictArry, @"Videos",
                                     nil] retain];


Tobi
Of course you then have to release them at the appropriate time
Tobi
Objects getting deallocated won't cause variables that point to those objects to get set to nil. The variables will still point to the now-dead objects, and trying to use them will cause a crash.
Peter Hosey
Moreover, the dictionary (like any Cocoa collection) will own anything that's put in it, so the array will not get deallocated as long as it's in the dictionary (and as long as you don't over-release it…).
Peter Hosey
A: 

I changed the postDict creation to this...

NSMutableDictionary *postDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                     [NSNumber numberWithBool:self.friendsOnly], @"IsFriendsOnly", 
                                     self.message, @"Message",
                                     self.shortText, @"ShortText",
                                     self.authorId, @"AuthorId",
                                     self.recipientId, @"RecipientId",
                                     self.language, @"Language",
                                     self.lat, @"Lat",
                                     self.lng, @"Lng",
                                     nil];

    [postDict setObject:imgDictArry forKey:@"Images"];
    [postDict setObject:movDictArry forKey:@"Videos"];

and it's fixed. But I don't know why.

E-Madd
E-Madd: Read Zoran Simic's answer.
Peter Hosey
Ohhhhh. Makes sense. Thanks
E-Madd