$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

    View Slide

  2. Confession: I’m a Rubyist

    View Slide

  3. Ruby is awesome
    class Post
    belongs_to :user
    end
    Post.where('created_at > ?', date).order(‘title’)

    View Slide

  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];

    View Slide

  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];

    View Slide

  6. LLVM to the rescue!

    View Slide

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

    View Slide

  8. (*) WTF is modern runtime?

    View Slide

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

    View Slide

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

    View Slide

  11. (*) WTF is modern runtime?
    • “non-fragile variables”
    • iOS
    • OSX 10.5+ (64-bit)

    View Slide

  12. Instance variables for @property
    Before:
    // MyKlass.h
    @interface MyKlass {
    NSMutableArray *list;
    }
    @property NSMutableArray *list;
    @end

    View Slide

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

    View Slide

  14. Blocks (closures)
    OSX 10.6 / iOS 4.0

    View Slide

  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);
    }

    View Slide

  16. Private variables
    Xcode 4.2 + LLVM + modern runtime

    View Slide

  17. Private variables
    Before - variables in a header file:
    // MyKlass.h
    @interface MyKlass {
    NSMutableArray *list;
    }
    @end
    (@protected by default)

    View Slide

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

    View Slide

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

    View Slide

  20. Automatic Reference Counting
    Xcode 4.2 + OSX 10.6 64-bit / iOS 4.0

    View Slide

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

    View Slide

  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
    }

    View Slide

  23. ARC
    Before:
    - (void) dealloc {
    [window release];
    [panel release];
    [notifier unsubscribe: self];
    [super dealloc];
    }

    View Slide

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

    View Slide

  25. ARC
    Before:
    NSAutoreleasePool *pool =
    [[NSAutoreleasePool alloc] init];
    // ...
    [pool drain];

    View Slide

  26. ARC
    After:
    @autoreleasepool {
    // ...
    }

    View Slide

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

    View Slide

  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;

    View Slide

  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

    View Slide

  30. GC: deprecated in OSX 10.8

    View Slide

  31. Forward method declarations
    Xcode 4.3

    View Slide

  32. Forward method declarations
    Problem:
    @implementation MyKlass
    - (void) bar {
    [self foo]; // <-- Xcode: wtf is this
    }
    - (void) foo {
    }
    @end

    View Slide

  33. Forward method declarations
    Before:
    @interface MyKlass ()
    - (void) foo;
    @end
    @implementation MyKlass
    - (void) bar {
    [self foo];
    }
    // ...

    View Slide

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

    View Slide

  35. Automatic @synthesize
    Xcode 4.4 + modern runtime

    View Slide

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

    View Slide

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

    View Slide

  38. ObjC literals
    Xcode 4.4

    View Slide

  39. Literals
    Before:
    [NSNumber numberWithBool: YES]
    [NSNumber numberWithInt: 1]
    [NSNumber numberWithFloat: x]
    After:
    @1, @2.5, @YES, @(x)

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  43. Array & dictionary subscripting
    Xcode 4.4 + OSX 10.6 modern runtime / iOS 5

    View Slide

  44. Subscripting
    Before:
    [array objectAtIndex: 2]
    [array replaceObjectAtIndex: 0 withObject: @”first”]
    After:
    array[2]
    array[0] = @”first”

    View Slide

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

    View Slide

  46. Subscripting
    Make your own array!
    - (id) objectAtIndexedSubscript: (NSUInteger) i {
    return list[i];
    }
    NSLog(@”record = %@”, collection[5]);

    View Slide

  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”]);

    View Slide

  48. Works on iOS 4.3 with libarclite
    http://petersteinberger.com/blog/2012/using-subscripting-with-Xcode-4_4-and-iOS-4_3/

    View Slide

  49. Extras from Foundation

    View Slide

  50. JSON parsing
    OSX 10.7 / iOS 5.0

    View Slide

  51. JSON parsing
    Before:
    TouchJSON / YAJL / JSON Framework / JSONKit / ...
    After:
    [NSJSONSerialization JSONObjectWithData: data
    options: 0
    error: &err];

    View Slide

  52. Regular expressions
    OSX 10.7 / iOS 4.0

    View Slide

  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)];

    View Slide

  54. Sources
    • https://developer.apple.com
    • http://stackoverflow.com
    • https://developer.apple.com/library/ios/#releasenotes/
    ObjectiveC/ObjCAvailabilityIndex/
    • Google :)

    View Slide