Collection logic

Discussion in 'iOS Programming' started by nashyo, Jan 12, 2012.

  1. nashyo, Jan 12, 2012
    Last edited: Jan 12, 2012

    nashyo macrumors 6502

    nashyo

    Joined:
    Oct 1, 2010
    Location:
    Bristol
    #1
    How is my logic here...

    For each quiz question, there will be a selection of answers, feedback and an image. I have therefore created a class called Content with those properties:

    Code:
    NSMutableDictionary *totalContent = [NSMutableDictionary dictionaryWithCapacity:1];
    
    Content *page1 = [[content alloc] init];
    
    page1.questionName = @"This is question 1";
    page1.answer1 = @"This is answer 1";
    page1.answer2 = @"This is answer 2";
    etc
    
    [totalContent addObject:page1 forKey:@"first"];
    However, I just watched a lecture from Stanford University on iTunes, and the lecture was talking about retrieving an array of dictionaries from Flickr to work with.

    I presume the dictionaries would contain objects like photo name, photo description, Image, with keys for each. But why have an array of dictionary's? Why not have it set up like I have done above?

    I'm struggling to understand these concepts. Please help.
     
  2. ArtOfWarfare macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #2
    Because an array works like this:

    Code:
    arrayWithObjects: zerothObject, firstObject, secondObject, thirdObject, ... nil
    and automatically, based on the order they're listed in, their indexes within the dictionary are assigned, so I can just say

    Code:
    [array objectAtIndex:1]
    and get firstObject.

    Whereas if I were using a dictionary it'd go something like

    Code:
    dictionaryWithObjectsAndKeys: firstObject, @"firstKey", secondObject, @"secondKey", thirdObject, @"thirdKey", ....
    accessing it would go like
    Code:
    [array objectAtIndex:@"firstKey"]
    to get firstObject.

    Now, you might think, okay, so creating it looks more messy, not a big deal, right?

    Wrong.

    Because with an array, I can access things dynamically. I can just say
    Code:
    [array objectAtIndex:i]
    And that can be the only line where I ever access any of the objects in the array. Whereas otherwise I'd have to create a separate thing for each case. (There's no way for it to know "first" corresponds to 1 and "second" corresponds to 2.)
     
  3. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #3
    An array is an ordered container. A dictionary is not inherently ordered. If you want to have 1000 questions in an array you just add them. 10,000 questions, no problem. For a dictionary using a key to order the values the way you're doing is a stretch. Will you use a key of @"ninety-ninth"? when you get to that question number? While it's not completely odd to order the values in a dictionary you would normally do it with NSNumbers as the keys, not strings containing First, second, third, etc. You'll find that to be impossibly cumbersome.
     
  4. nashyo thread starter macrumors 6502

    nashyo

    Joined:
    Oct 1, 2010
    Location:
    Bristol
  5. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #5
    Hey, guys. I think the OP was asking about an "array of dictionaries". So, then question, to me, is: What are the advantages of using an NSDictionary vs. a custom class? Discuss.
     
  6. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #6
    Using a NSDictionary with known names for the stored keys as opposed to a custom class with properties for these keys is generally not seen as such a good design. My understanding for this is that whilst you can use constants for the keys it does not require that the constants are used which can result in difficult to debug errors.
     
  7. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #7
    @dejo, I'm not certain that that was his question but what the hey?

    I use dictionaries in this way an awful lot and it works well. I also sometimes use custom classes. The cases I use custom classes have included for efficiency reasons and because the object needed some more smarts than just being a bag of stuff.

    In the efficiency case I had a data structure that contained a lot of dictionaries and each one had some numbers and a few points and rects that were stored as NSValues. Profiling told me that the code that accessed this data structure was slow and I changed it to a custom class where the CGPoints and CGRects were ivars, along with some strings, also as ivars. Profiling told me that this was much faster than getting/setting the rects and points from NSValue so I stuck with the custom class.

    In another case I have a class that represents a person. It has a number of properties, like first name, last name, and a bunch of other ones. There are also some synthesized properties, like full name. This class has a dictionary, which contains all the properties. I also added setObject:forKey and objectForKey: methods so it looks like a dictionary. The implementation of objectForKey first checks the dictionary and then if the value isn't there, like the full name, then it creates the value and stores it in the dictionary. There are other kinds of smarts associated with the person object as well. But it doesn't have @properties for first name etc. They are just accessed via objectForKey:

    So the dictionary works well in the general case where you need a bag of stuff but if you need something special then a custom class may be required.

    I often use a typedef in this case. Something like

    typedef NSMutableDictionary MyPerson;

    and use MyPerson everywhere in the code. This is self-documenting what the purpose of the object is, at least better than NSMutableDictionary, and if I decide after a while that I need a custom class it's easier to change the code.
     
  8. MattInOz macrumors 68030

    MattInOz

    Joined:
    Jan 19, 2006
    Location:
    Sydney
    #8
    I guess in the Sanford example they don't control the data source but they have a published format that can map to key / value pairs. The method sucking in the data doesn't need to care about what the data means beyond that. If more or less stuff arrives you end up with more or less pairs, if stuff could arrive in a different order then you don't have to determine that at dataloading the order.
     

Share This Page