Objective-C Is Not Java


Published on

Look past the square braces and the damned header files and Objective-C -- the essential language of iOS development -- really isn't that different from other object-oriented languages. Classes, single-inheritance, polymorphism, implementation hiding... check, check, check, and check. So it's really not that difficult for old Java / Python / Ruby / C++ dogs to learn new tricks once they install Xcode, right?
To be a competent Obj-C programmer, not that hard.
To be a great Obj-C programmer... now that's another story.
In this session, we will look at traits that are unique to Objective-C, the tricks that bring out the expressiveness and power of the language. We'll also look at how to write idiomatic code that will be easily understood and maintained by other Objective-C developers. We'll look at how Automatic Reference Counting resembles but is really nothing like Garbage Collection, how properties put plain old instance variables to shame, how we loosely couple classes with delegates and notification, how blocks help us un-block our code by simplifying asynchronicity, and more.

Published in: Technology
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Objective-C Is Not Java

  1. Objective-C Is Not Java Chris Adamson • @invalidname CodeMash 2013
  2. What This Is• A guide to writing idiomatic Obj-C code • Easier to write • Easier to maintain• Based on current real-world conventions
  3. What This Is Not• An advocacy piece for Objective-C• A slam on your favorite language
  4. Scope• Covering Objective-C as used in OS X / iOS SDKs • Obj-C is effectively owned by Apple • Language versions are now tied to releases of Xcode• We are not concerned with Obj-C use outside of Apple ecosystem, nor advocating it• No history lesson today
  5. Start with a Demo
  6. Classes and Objects• There is no root class, just the C pointer id typedef struct objc_class *Class;typedef struct objc_object { Class isa;} *id;• Can call any method on id• That said, effectively everything in the SDK subclasses NSObject
  7. Methods / messages• Call a method on an object with [] •[foo bar]; •[foo bar: 1 withBaz: 2];• Method calls are really message dispatches• OK for foo to be nil. Not OK if foo’s class doesn’t understand bar or bar:withBaz: • 🙅 Don’t check variables for nil.
  8. New objects• alloc allocates memory for a new object, init sets up its state. Always do both. NSMutableArray *mutableSessions = [[NSMutableArray alloc] init]; • [Class new] is equivalent to [[Class alloc] init]. 🙅 Nobody uses it.• Some classes have convenience initializers: [NSURL URLWithString:] instead of [[NSURL alloc] initWithString:]
  9. Initializers• Some classes have many initializers for different purposes • NSString — initWithData:encoding:, initWithUTF8String:, etc.• Designated initializer — the initializer that sets the most state; other initializers can call this with default values
  10. End-of-life• dealloc is called when an object is being destroyed. Override for needed cleanup, end with [super dealloc] • 🙆 Can actually count on this, unlike Java’s finalize()• Not as big a deal as it used to be (see ARC, later)
  11. Class files• Typically, you create two files • Header (.h) for anything pubic. Contains the Obj-C @interface directive • Implementation (usually .m) for anything private. Contains @implementation. • 🙍 No equivalent of Java protected (i.e., only accessible by subclasses) or C++ friendly
  12. Importing headers• C’s #include copies all of a file (usually a .h) into a compile. Obj-C’s #import is similar, but avoids copying same file twice. • 🙆 Always prefer #import in Obj-C code• “Class.h” looks in current directory, <Framework/Class.h> searches paths.• @class is a forward declaration, used to break circular dependencies in headers
  13. Namespaces• Objective-C does not have namespaces. 🙍• Accepted practice is class naming convention: • Apple prefixes classes with 2 uppercase letters (NS, UI, CA, SK, AV, etc.) • Your classes should use a 3-letter prefix • Xcode project creation now prompts for this
  14. CMHSession.h#import <Foundation/Foundation.h>@interface CMHSession : NSObject@property (copy) NSString *speakerName;@property (copy) NSString *title;@property (copy) NSString *abstract;@property (copy) NSString *room;@property (strong) NSDate *start;@property (copy) NSString *technology;@property (copy) NSURL *url;@property (copy) NSString *userComments;@property (assign) NSInteger *userScore;-(id) initWithJSONDictionary: (NSDictionary*) dict;@end
  15. @implementation• Method implementations go here, in .m file • Public methods (from .h) and private • Private methods used to have to be in order you called them (caveat on next slide), but that doesn’t matter with LLVM multi-pass compile
  16. Class Extension• Like a second @interface, but in the .m file (and therefore only visible within that file)• Obj-C’s equivalent to the C forward declaration • Not visible to subclasses 🙍• Mostly used now for private properties (see later slide)
  17. Class Extension@interface CMHSessionNotesViewController ()- (IBAction)handleDoneTapped:(id)sender;@property (weak, nonatomic) IBOutlet UITextView *notesView;@end@implementation CMHSessionNotesViewController- (IBAction)handleDoneTapped:(id)sender {// method implementation goes here}@endNote: The @interface mus! be named ClassName()
  18. Categories• Allow you to add methods to classes you don’t own (including Apple’s!) • Cannot add state (instance variables, properties)• Often added to NSString, collections• By convention, file name is ClassName +CategoryName
  19. NSArray+BoundsChecking.h #import <Foundation/Foundation.h> @interface NSArray (BoundsChecking) -(id) firstObject; @end
  20. NSArray+BoundsChecking.m #import "NSArray+BoundsChecking.h" @implementation NSArray (BoundsChecking) -(id) firstObject { if ([self count] == 0) { return nil; } return [self objectAtIndex:0]; } @end
  21. Protocols • List of methods, similar to Java interface • Group methods together under the @required and @optional directives. • Classes declare their implementation of protocol with <> after declaring subclass@interface CMHSessionListViewController : UIViewController<UITableViewDataSource, UITableViewDelegate>
  22. Memory Management• Obj-C uses reference counting, not garbage collection 🙅• Any object you create (alloc, copy) must eventually be release’d. • To keep an object around, call retain, then release when done.• This mostly doesn’t matter anymore, because…
  23. Automatic Reference Counting• LLVM understands the retain/release rules, and applies them for you. You no longer write retain/release. • It’s still not GC. Objects freed immediately when reference count equals zero• Can be enabled at the project or file level• 🙆 Everyone’s using it now.
  24. Properties• An instance variable combined with getter/ setter methods, all built for you by the compiler.• Declaration also specifies threading, memory management, and writability• Accessed via the dot operator, not brackets
 self.speakerName = [dict valueForKey:@"SpeakerName"];
 cell.speakerLabel.text = session.speakerName;
  25. Property attributes• readonly / readwrite• nonatomic — Concurrent access OK. Used for UIKit (which should only ever be called from main thread)• strong / weak — Whether this object retains the property, thereby keeping it from being freed • Also assign (for primitives), copy
  26. Property naming• For property foo, synthesized ivar is _foo, getter is foo, setter is setFoo: • @synthesize directive lets you specify/ rename property variable or methods. • 🙅 Never use get in a method name• 💁 For BOOLs, use adjectiv" or #erbsNou$ style, e.g., editable or allowsEditing
  27. Other Naming Conventions• Method names should imply their argument • What does [sort: YES] mean? • How about [sort: @”name”] ? • Aren’t these better as [sortAscending: YES] , [sortByProperty:@”name”] ?• Callbacks often start with who’s calling: tableView:didSelectRowAtIndexPath:
  28. Grand Central Dispatch• Threads are good on multi-core, but how many threads are ideal? • The OS is in the best position to know, so let it decide • Organize work into discrete blocks, give it to the system and let it figure out how to run it
  29. Blocks• Closures for C, or function pointers that capture their enclosing scope • Start with ^ character, then return types, parameter list, and code in {…}. • Commonly used as “completion handlers” for long-running operations (network, media, etc.) • Example to follow…
  30. UIKit Threading• All access to UIKit must be on the main thread (sound like AWT/Swing, anyone?) • UI events will come from this thread. Network callbacks often won’t.• Long-running tasks must not be on main thread, or they’ll block the UI (sound like AWT/Swing, anyone?) 🙍
  31. GCD Recipes• Put work on other threads with C function dispatch_async(), which takes a GCD queue and a block to execute • To get off main thread, get queue with dispatch_get_global_queue() • To get o$ main thread, use dispatch_get_main_queue()
  32. Off main queue and back ondispatch_async(dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // perform long-running task dispatch_async(dispatch_get_main_queue(), ^{ // update the ui });});
  33. Speaking of C Available on iBooks
  34. Apple still loves C• Utility routines that don’t need to be tied to a class are often C functions: e.g, NSLog()• High-performance frameworks are in C• Constants may be enums in a typedef enum { NSOrderedAscending = -1, NSOrderedSame, NSOrderedDescending};typedef NSInteger NSComparisonResult;
  35. All objects are pointers • All Obj-C object declarations take *, because they’re pointers • Except for type id, which is already a pointer • ** means “pointer to object”, used when populating as a side effectNSError *jsonErr = nil;id jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&jsonErr];
  36. A Slide on Frameworks• Apple’s stuff is packaged as “frameworks” (not “libraries”), in .framework bundles • Framework = executable library + headers + documentation + resources (graphics, sound, localizations, etc.)• The bigs: UIKit, Foundation• Not easy to create your own with Xcode
  37. Apple’s Favorite Patterns• MVC (you all know this 🙆)• Target-Action• Key-Value Coding• Delegation• Completion Handler
  38. Target-Action• Indicates how an event (like a button tap) is to be handled. Sender is provided with: • Action: a method signature as a @selector • Target: object to call the method on• Method signature must be known in advance. UIKit most commonly uses
 -(IBAction) action:(id) sender
  39. Key-Value Coding• Allows access into nested object structures as a dot-separated string (e.g., “user.name” in a tweet returned by Twitter API) • Each key segment is fetched by valueForKey:, which looks for property or ivar of that name (or could be overridden)• Used for sorting collections, also with “magic” key path members (“@avg.value”, “@min.date”)
  40. Delegation• Common means of extending a class’ functionality, by making defined callbacks to one object that you write. • Methods usually collected in a protocol • You declare that your object implements the protocol, then set it as the delegate property of the other class• 🙅 We don’t subclass much in iOS. This is why.
  41. Completion Handler• A block to be completed when a long-running task (animation, network access) completes. • Parameters to the block may provide results of the task • For anything else you need, remember that everything in scope prior to the block’s creation is available inside the block
  42. A look inside our demo
  43. Modern Obj-C habits• Only use .h for public stuff • All private stuff (properties, methods) can now go in a class extension in the .m• Prefer private properties to instance variables• Get off the main thread; blocks are cheap
  44. Old Habits Die Hard• Obj-C literals in Xcode 4.4• Arrays: @[…] instead of [NSArray arrayWithObjects:…]• Dictionaries @{ name1:value1, name2:value2, …} instead of [NSDictionary dictionaryWithValuesAndKeys:…]• Accessors: array[i], dict[“key”]
  45. Final Thoughts• Obj-C / Cocoa have consistent idioms you’ll see in Apple’s frameworks. • Adopt them, emulate them, don’t fight them• Like any language, Obj-C has its share of good and bad. • Unfamiliar != bad
  46. Learn More!Available on iBooks Available at pragprog.com