Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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. 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];
  2. 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];
  3. Instance variables for @property Before: // MyKlass.h @interface MyKlass {

    NSMutableArray *list; } @property NSMutableArray *list; @end
  4. 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); }
  5. Private variables Before - variables in a header file: //

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

    MyKlass.m @interface MyKlass () { NSMutableArray *list; } @end
  7. ARC Before: - (NSArray *) views { NSMutableArray *arr =

    [[NSMutableArray alloc] init]; UIView *view = [[UIView alloc] initWithFrame: frame]; [arr addObject: view]; [view release]; return [arr autorelease]; }
  8. 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 }
  9. ARC Before: - (void) dealloc { [window release]; [panel release];

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

    magically released [notifier unsubscribe: self]; // [super dealloc] is actually forbidden }
  11. 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;
  12. 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
  13. Forward method declarations Problem: @implementation MyKlass - (void) bar {

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

    @end @implementation MyKlass - (void) bar { [self foo]; } // ...
  15. Automatic @synthesize Before: @interface MyKlass @property NSString *name; @end @implementation

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

    MyKlass - (void) printName { NSLog(@”%@ %@”, _name, self.name); } @end
  17. Literals Before: [NSArray arrayWithObjects: @”twitter”, @”facebook”, @”github”, nil] [NSDictionary dictionaryWithObjectsAndKeys:

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

    @”Kuba”, @”firstName”, @”Suder”, @”lastName”, [NSNumber numberWithInt: 30], @”age”, nil]
  19. Subscripting Make your own array! - (id) objectAtIndexedSubscript: (NSUInteger) i

    { return list[i]; } NSLog(@”record = %@”, collection[5]);
  20. 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”]);
  21. JSON parsing Before: TouchJSON / YAJL / JSON Framework /

    JSONKit / ... After: [NSJSONSerialization JSONObjectWithData: data options: 0 error: &err];
  22. 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)];