Monday, November 4, 2013

Objective C Checklist

As I move closer to production with an app that may get a lot of uptake, I developed the following good practices checklist:


From Effective Objective C 2.0

  • Just designate @class when possible — minimizes leakage (remember no real (complier) enforcement of private) in Objective C
  • Use literal constructors, e.g., rather than NSNumber *someNumber = [NSNumber numberWithInteger:1], use NSNumber *someNumber = 01; --searching for "with" might be effective
  • Use static constants rather than #define, e.g., rather than #define ANIMATION_DURATION 0.3 use static const NSTimeInterval kAnimationDuration = 0.3;
  • @property (nonatomic, readwrite, copy)
    • Sort of obvious ones except for copy -- use copy for strings (which may or may NOT be mutable -- NSMutableString might get passed in, which could lead to weird unexpected behavior), assign works for scalars, but there's also strong and weak (for avoiding circular references that would confuse ARC)
    • One other caveat, if in the “readwrite" slot, retain is also an option -- retain should be used for pointers (and copy, etc. become irrelevant), e.g., @property (nonatomic, strong) NSObject *aThing; retain has been deprecated (replaced with strong) in ARC per
  • Implement description method, e.g.,  (although, if you don’t have any instance variables/properties that are informative, it's probably not worthwhile & you don't, don't don't want to overwrite the autogenerated CoreDataModel code)

  -(NSString *) description{

return [NSString stringWithFormat:@"<%@: %p,  \"%@ %@\">", 

[self class], self, _firstName, _lastName];


  • Define private instance variables in the implementation file. This is done by defining another @interface in the .m file, and prevents leaking -- Although I understand this at the level of "a reasonable workaround for deficiencies in the language"  I do find it a bit off-putting: I like ALL definitions in the .h files (although being a Java/Lisp guy, I hate .h files).  BTW the syntax for this is  (the parens matter!!!)

@interface HCSituationEvaluator ()



  • Use NSCache rather than NSDictionary for caching (didn’t realize this class even existed)

From iOS Programming, The Big Nerd Ranch Guide

  • Set breakpoint to break on all errors



    • Consider using removeObjectIdenticalTo, rather than removeObject (the right answer depends upon the circumstance: removeObject calls isEqual, so it doesn’t require exact instance identity)
    • Check setDelegate in xml parser — the recommendation is to have delegates for each sub node in the xml parse tree. This makes sense, and makes for more maintainable code that building your own stack based state machine. However, I'm a more skeptical of rolling all the parsing into the class associated with that node, primarily because the parsed data may be stored in CoreData, or in a custom datastore. In these cases, I tend to have side classes that can handle “out of band” operations, and put the parsing there, using the pattern CoreDataClassNameHelper
      • HOWEVER (& Critically Importantdelegate is a weak reference, you need to hold onto the value somewhere else or the memory will be reused!


Some "older" writeups advise you to avoid storyboards. This seems to be out of date with Xcode 5, which doesn't present you with a non-storyboard option.


    • Penultimate step "Apple reserves the right to useall two letter class prefixes"
    • Final step, be sure all situation eval is done via notifications and timed events e.g., performSelector:@selector(aSelector) withObject:nilafterDelay:0.5

No comments: