$30 off During Our Annual Pro Sale. View Details »

What’s new(ish) in ObjectiveC

What’s new(ish) in ObjectiveC

An overview of various syntax and compiler improvements that appeared in ObjC in the last few years, which make the code simpler and more DRY. Most of these were made possible by switching from GCC to Apple's own compiler infrastructure (LLVM). This includes:

* automatic generation of instance variables for @properties
* blocks (closures, lambdas)
* possibility to declare private instance variables in *.m file
* ARC (Automatic Reference Counting)
* automatic forward method declarations
* automatic @synthesize for @properties
* ObjC literals and array/dictionary subscripting

Two useful additions to Foundation.framework are also mentioned:

* NSJSONSerialization for JSON parsing
* NSRegularExpression for matching strings with regular expressions

Kuba Suder

April 04, 2013
Tweet

More Decks by Kuba Suder

Other Decks in Programming

Transcript

  1. What’s new(ish) in ObjectiveC Kuba Suder @psionides • jsuder •

    http://psionides.eu • Lunar Logic
  2. Confession: I’m a Rubyist

  3. Ruby is awesome class Post belongs_to :user end Post.where('created_at >

    ?', date).order(‘title’)
  4. ObjC sometimes makes me cry NSManagedObjectContext * context = [[NSApp

    delegate] managedObjectContext]; NSManagedObjectModel * model = [[NSApp delegate] managedObjectModel]; NSDictionary * entities = [model entitiesByName]; NSEntityDescription * entity = [entities valueForKey:@"Post"]; NSPredicate * predicate; predicate = [NSPredicate predicateWithFormat:@"creationDate > %@", date]; NSSortDescriptor * sort = [[NSSortDescriptor alloc] initWithKey:@"title"]; NSArray * sortDescriptors = [NSArray arrayWithObject: sort]; NSFetchRequest * fetch = [[NSFetchRequest alloc] init]; [fetch setEntity: entity]; [fetch setPredicate: predicate]; [fetch setSortDescriptors: sortDescriptors]; NSArray * results = [context executeFetchRequest:fetch error:nil]; [sort release]; [fetch release];
  5. ObjC sometimes makes me cry NSManagedObjectContext * context = [[NSApp

    delegate] managedObjectContext]; NSManagedObjectModel * model = [[NSApp delegate] managedObjectModel]; NSDictionary * entities = [model entitiesByName]; NSEntityDescription * entity = [entities valueForKey:@"Post"]; NSPredicate * predicate; predicate = [NSPredicate predicateWithFormat:@"creationDate > %@", date]; NSSortDescriptor * sort = [[NSSortDescriptor alloc] initWithKey:@"title"]; NSArray * sortDescriptors = [NSArray arrayWithObject: sort]; NSFetchRequest * fetch = [[NSFetchRequest alloc] init]; [fetch setEntity: entity]; [fetch setPredicate: predicate]; [fetch setSortDescriptors: sortDescriptors]; NSArray * results = [context executeFetchRequest:fetch error:nil]; [sort release]; [fetch release];
  6. LLVM to the rescue!

  7. Instance variables for @property Requires: modern runtime(*)

  8. (*) WTF is modern runtime?

  9. (*) WTF is modern runtime? • “non-fragile variables”

  10. (*) WTF is modern runtime? • “non-fragile variables” • iOS

  11. (*) WTF is modern runtime? • “non-fragile variables” • iOS

    • OSX 10.5+ (64-bit)
  12. Instance variables for @property Before: // MyKlass.h @interface MyKlass {

    NSMutableArray *list; } @property NSMutableArray *list; @end
  13. Instance variables for @property After: // MyKlass.h @interface MyKlass @property

    NSMutableArray *list; @end
  14. Blocks (closures) OSX 10.6 / iOS 4.0

  15. Blocks // calling [list enumerateObjectsUsingBlock: ^(id obj, NSUInteger i, BOOL

    *stop) { NSLog(@”#%d = %@”, i, obj); }]; // declaring - (void) connectTo: (NSString *) url callback: (void (^)(NSString *)) callback { NSString *response = [connector requestTo: url]; callback(response); }
  16. Private variables Xcode 4.2 + LLVM + modern runtime

  17. Private variables Before - variables in a header file: //

    MyKlass.h @interface MyKlass { NSMutableArray *list; } @end (@protected by default)
  18. Private variables Xcode 4 + LLVM - class extension: //

    MyKlass.m @interface MyKlass () { NSMutableArray *list; } @end
  19. Private variables Xcode 4.2 + LLVM: // MyKlass.m @implementation MyKlass

    { NSMutableArray *list; } @end
  20. Automatic Reference Counting Xcode 4.2 + OSX 10.6 64-bit /

    iOS 4.0
  21. ARC Before: - (NSArray *) views { NSMutableArray *arr =

    [[NSMutableArray alloc] init]; UIView *view = [[UIView alloc] initWithFrame: frame]; [arr addObject: view]; [view release]; return [arr autorelease]; }
  22. ARC After: - (NSArray *) views { NSMutableArray *arr =

    [[NSMutableArray alloc] init]; UIView *view = [[UIView alloc] initWithFrame: frame]; [arr addObject: view]; // view magically released return arr; // arr magically autoreleased }
  23. ARC Before: - (void) dealloc { [window release]; [panel release];

    [notifier unsubscribe: self]; [super dealloc]; }
  24. ARC After: - (void) dealloc { // window and panel

    magically released [notifier unsubscribe: self]; // [super dealloc] is actually forbidden }
  25. ARC Before: NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // ...

    [pool drain];
  26. ARC After: @autoreleasepool { // ... }

  27. ARC Before: @property (retain) NSWindow *window; After: @property (strong) NSWindow

    *window;
  28. ARC Before: @property (assign) id delegate; After: @property (unsafe_unretained) id

    delegate; Or better (OSX 10.7 / iOS 5) - set to nil when object is released: @property (weak) id delegate;
  29. ARC • calling dealloc, retain, release, autorelease or retainCount is

    verboten • you have to follow the rules • using CFCreateThingie() requires extra keywords/wrapping • can be enabled/disabled per file
  30. GC: deprecated in OSX 10.8

  31. Forward method declarations Xcode 4.3

  32. Forward method declarations Problem: @implementation MyKlass - (void) bar {

    [self foo]; // <-- Xcode: wtf is this } - (void) foo { } @end
  33. Forward method declarations Before: @interface MyKlass () - (void) foo;

    @end @implementation MyKlass - (void) bar { [self foo]; } // ...
  34. Forward method declarations After: // yay, no @interface! @implementation MyKlass

    - (void) bar { [self foo]; } - (void) foo { } @end
  35. Automatic @synthesize Xcode 4.4 + modern runtime

  36. Automatic @synthesize Before: @interface MyKlass @property NSString *name; @end @implementation

    MyKlass @synthesize name; - (void) printName { NSLog(@”%@ %@”, name, self.name); } @end
  37. Automatic @synthesize After: @interface MyKlass @property NSString *name; @end @implementation

    MyKlass - (void) printName { NSLog(@”%@ %@”, _name, self.name); } @end
  38. ObjC literals Xcode 4.4

  39. Literals Before: [NSNumber numberWithBool: YES] [NSNumber numberWithInt: 1] [NSNumber numberWithFloat:

    x] After: @1, @2.5, @YES, @(x)
  40. Literals Before: [NSArray arrayWithObjects: @”twitter”, @”facebook”, @”github”, nil] [NSDictionary dictionaryWithObjectsAndKeys:

    @”Kuba”, @”firstName”, @”Suder”, @”lastName”, [NSNumber numberWithInt: 30], @”age”, nil]
  41. Literals Before: [NSArray arrayWithObjects: @”twitter”, @”facebook”, @”github”, nil] [NSDictionary dictionaryWithObjectsAndKeys:

    @”Kuba”, @”firstName”, @”Suder”, @”lastName”, [NSNumber numberWithInt: 30], @”age”, nil]
  42. Literals After: @[@”twitter”, @”facebook”, @”github”] @{ @”firstName”: @”Kuba”, @”lastName”: @”Suder”,

    @”age”: @30 }
  43. Array & dictionary subscripting Xcode 4.4 + OSX 10.6 modern

    runtime / iOS 5
  44. Subscripting Before: [array objectAtIndex: 2] [array replaceObjectAtIndex: 0 withObject: @”first”]

    After: array[2] array[0] = @”first”
  45. Subscripting Before: [dictionary objectForKey: @”id”] [dictionary setObject: @”jsuder” forKey: @”author”]

    After: dictionary[@”id”] dictionary[@”author”] = @”jsuder”
  46. Subscripting Make your own array! - (id) objectAtIndexedSubscript: (NSUInteger) i

    { return list[i]; } NSLog(@”record = %@”, collection[5]);
  47. Subscripting Make your own dictionary! - (id) objectAtKeyedSubscript: (id) key

    { for (Node *node in tree) { if ([node.name isEqual: key]) return node; } return nil; } NSLog(@”node = %@”, xmlDocument[@”date”]);
  48. Works on iOS 4.3 with libarclite http://petersteinberger.com/blog/2012/using-subscripting-with-Xcode-4_4-and-iOS-4_3/

  49. Extras from Foundation

  50. JSON parsing OSX 10.7 / iOS 5.0

  51. JSON parsing Before: TouchJSON / YAJL / JSON Framework /

    JSONKit / ... After: [NSJSONSerialization JSONObjectWithData: data options: 0 error: &err];
  52. Regular expressions OSX 10.7 / iOS 4.0

  53. Regular expressions Before: RegexKit / RegexKitLite After: NSString *pattern =

    @”^\\w+@\\w+(\\.\\w+)+$”; NSRegularExpression *re = [NSRegularExpression regularExpressionWithPattern: pattern options: 0 error: &err]; [re matchesInString: email options: 0 range: NSMakeRange(0,20)];
  54. Sources • https://developer.apple.com • http://stackoverflow.com • https://developer.apple.com/library/ios/#releasenotes/ ObjectiveC/ObjCAvailabilityIndex/ • Google

    :)