6

Data comes from the server in JSON, which is placed in a NSDictionary. Depending on type of requested data the new class object will be created from this NSDictionary. There're a lot of data comes, so the object holds a reference to NSDictionary and extracts a value only when referring to a particular variable. Something like lazy initialization:

- (NSString *)imgURL {
    if (_imgURL == nil) {
        _imgURL = [self makeObjForKey:kImageURL];
    }
    return _imgURL;
}

This significantly increases application speed, but produces other problems:

  1. If a value is absent in NSDictionary, it remains nil. Then for each subsequent call to this variable there occurs search for it in NSDictionary.
  2. When copying the entire instance of the class (NSCopying protocol), all variables are copied, producing convertion from entire NSDictionary.

Solutions:

  1. Put some flag indicating that value has been checked. But then you have to add additional checks
  2. Only copy NSDictionary for object instance, but then later have to parse same variables again

Anyway these solutions are not optimal. Maybe somebody faced with a similar problem and can advise other techniques.

Lion
  • 1,264
  • 1
  • 17
  • 23
  • 1
    I'm agree with Rob Napier's answer. Make sure that there really is a need to optimize calls to NSDictionary. Try to profile your code (using Instruments) and have a look at the amount of time which calls to NSDictionary have. It is very likely to be negligible. – FreeNickname Jan 23 '14 at 17:26

1 Answers1

3

NSDictionary lookups are very fast. Unless this is a truly enormous dictionary, I wouldn't worry too much about the lookup. If you have some properties that are checked particularly often, then you could optimize them with a special flag, but I usually wouldn't worry about it.

For copying, my first recommendation is to make this object a value (immutable) object. Initialize it once with JSON and then provide no mutators (that may be what you're doing already). Then copy is trivial; just return self. You don't need to make a real copy, because all copies are interchangeable. One of the great benefits of value objects is how cheap and easy they are to copy.

If you sometimes really need a mutable version, then follow the NSArray/NSMutableArray pattern. Then only the mutable version will have to deal with copies (in which case you should just copy the dictionary; not the cached objects).

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • 3
    `Unless this is a truly enormous dictionary, I wouldn't worry too much` and even then, lookups should still be O(1) assuming a good hashing algorithm. Certainly no where near O(n) – James Webster Jan 23 '14 at 16:32
  • Thanks! Mutable/immutable pattern sounds good, I'll try it. Actually, more often mutable objects not needed for me, but some of them can be updated with extra meta data, which will be downloaded later. So in this case is it better to make new extended object by coping initial one (with less data) and adding to it new values, or to make initial object mutable and just update new variables in it? – Lion Jan 24 '14 at 07:32
  • 1
    When in doubt, go immutable. Consider whether this extra metadata really belongs in the same dictionary (or even in the same object). Always think about HAS-A patterns. Could your one object hold data (immutable) dictionary and a separate metadata (immutable) dictionary. Should there be a specific object to hold data and another to hold metadata (and then a parent that joins them)? Immutability helps push you towards these HAS-A patterns, which have their own benefits. – Rob Napier Jan 24 '14 at 13:19
  • I thought about it from your first answer. It's really good idea to keep meta and general information separately, especially to hash them on device. I think I modify current model to make these things done. Anyway it provides better readability. Thanks! – Lion Jan 24 '14 at 20:41