Your SlideShare is downloading. ×
0
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Modern Objective-C @ Pragma Night

2,119

Published on

Slides from Modern Objective-C by Giuseppe Arici @ Pragma Night

Slides from Modern Objective-C by Giuseppe Arici @ Pragma Night

Published in: Technology
0 Comments
7 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,119
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
74
Comments
0
Likes
7
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Modern Objective-C Giuseppe Arici Pragma Night @ Talent Garden
  • 2. It’s All About ...Syntactic Sugar Pragma Night
  • 3. Unordered Method Declarations Pragma Night
  • 4. Public & Private Method Ordering @interface SongPlayer : NSObject - (void)playSong:(Song *)song; @end @implementation SongPlayer - (void)playSong:(Song *)song { NSError *error; [self startAudio:&error]; /* ... */ } - (void)startAudio:(NSError **)error { /* ... */ } Warning: @end instance method -startAudio: not found (return type defaults to id) Pragma Night
  • 5. Wrong WorkaroundIn the public interface @interface SongPlayer : NSObject - (void)playSong:(Song *)song; - (void)startAudio:(NSError **)error; @end @implementation SongPlayer - (void)playSong:(Song *)song { NSError *error; [self startAudio:&error]; /* ... */ } - (void)startAudio:(NSError **)error { /* ... */ } @end Pragma Night
  • 6. Okay Workaround 1In a class extension @interface SongPlayer () - (void)startAudio:(NSError **)error; @end @implementation SongPlayer - (void)playSong:(Song *)song { NSError *error; [self startAudio:&error]; /* ... */ } - (void)startAudio:(NSError **)error { /* ... */ } @end Pragma Night
  • 7. Okay Workaround 2Reorder methods @interface SongPlayer : NSObject - (void)playSong:(Song *)song; @end @implementation SongPlayer - (void)startAudio:(NSError **)error { /* ... */ } - (void)playSong:(Song *)song { NSError *error; [self startAudio:&error]; /* ... */ } @end Pragma Night
  • 8. Best SolutionParse the @implementation declarations then bodies @interface SongPlayer : NSObject - (void)playSong:(Song *)song; @end @implementation SongPlayer - (void)playSong:(Song *)song { NSError *error; [self startAudio:&error]; Xcode 4.4+ /* ... */ } - (void)startAudio:(NSError **)error { /* ... */ } @end Pragma Night
  • 9. Enum with FixedUnderlying Type Pragma Night
  • 10. Enum with Indeterminate TypeBefore OS X v10.5 and iOS typedef enum { NSNumberFormatterNoStyle, NSNumberFormatterDecimalStyle, NSNumberFormatterCurrencyStyle, NSNumberFormatterPercentStyle, NSNumberFormatterScientificStyle, NSNumberFormatterSpellOutStyle } NSNumberFormatterStyle; //typedef int NSNumberFormatterStyle; Pragma Night
  • 11. Enum with Explicit TypeAfter OS X v10.5 and iOS enum { NSNumberFormatterNoStyle, NSNumberFormatterDecimalStyle, NSNumberFormatterCurrencyStyle, NSNumberFormatterPercentStyle, NSNumberFormatterScientificStyle, NSNumberFormatterSpellOutStyle }; typedef NSUInteger NSNumberFormatterStyle; • Pro: 32-bit and 64-bit portability • Con: no formal relationship between type and enum constants Pragma Night
  • 12. Enum with Fixed Underlying TypeLLVM 4.2+ Compiler typedef enum NSNumberFormatterStyle : NSUInteger { NSNumberFormatterNoStyle, NSNumberFormatterDecimalStyle, NSNumberFormatterCurrencyStyle, NSNumberFormatterPercentStyle, NSNumberFormatterScientificStyle, NSNumberFormatterSpellOutStyle } NSNumberFormatterStyle; Xcode 4.4+ • Stronger type checking • Better code completion Pragma Night
  • 13. Enum with Fixed Underlying TypeNS_ENUM macro typedef NS_ENUM(NSUInteger, NSNumberFormatterStyle) { NSNumberFormatterNoStyle, NSNumberFormatterDecimalStyle, NSNumberFormatterCurrencyStyle, NSNumberFormatterPercentStyle, NSNumberFormatterScientificStyle, NSNumberFormatterSpellOutStyle }; Xcode 4.4+ • Foundation declares like this Pragma Night
  • 14. Enum with Fixed Underlying TypeStronger type checking (-Wenum-conversion) NSNumberFormatterStyle style = NSNumberFormatterRoundUp; // 3warning:implicit conversion from enumeration type enumNSNumberFormatterRoundingMode to different enumeration typeNSNumberFormatterStyle (aka enum NSNumberFormatterStyle) Pragma Night
  • 15. Enum with Fixed Underlying TypeHandling all enum values (-Wswitch) - (void) printStyle:(NSNumberFormatterStyle) style{ switch (style) { case NSNumberFormatterNoStyle: break; case NSNumberFormatterSpellOutStyle: break; } }warning:4 enumeration values not handled in switch:NSNumberFormatterDecimalStyle,NSNumberFormatterCurrencyStyle,NSNumberFormatterPercentStyle... Pragma Night
  • 16. @Synthesize by Default Pragma Night
  • 17. Properties Simplify Classes@interface instance variables @interface Person : NSObject { NSString *_name; } @property(strong) NSString *name; @end @implementation Person @synthesize name = _name; @end Pragma Night
  • 18. Properties Simplify Classes@implementation instance variables @interface Person : NSObject @property(strong) NSString *name; @end @implementation Person { NSString *_name; } @synthesize name = _name; @end Pragma Night
  • 19. Properties Simplify ClassesSynthesized instance variables @interface Person : NSObject @property(strong) NSString *name; @end @implementation Person @synthesize name = _name; @end Pragma Night
  • 20. @Synthesize by DefaultLLVM 4.2+ Compiler @interface Person : NSObject @property(strong) NSString *name; @end @implementation Person Xcode 4.4+ @end Pragma Night
  • 21. Instance Variable Name !?Instance variables now prefixed with “_” @interface Person : NSObject @property(strong) NSString *name; @end @implementation Person - (NSString *)description { return _name; Xcode 4.4+ } /* as if youd written: @synthesize name = _name; */ @end Pragma Night
  • 22. Backward Compatibility !?Be careful, when in doubt be fully explicit @interface Person : NSObject @property(strong) NSString *name; @end @implementation Person @synthesize name; /* as if youd written: @synthesize name = name; */ @end Pragma Night
  • 23. To @Synthesize by Default• Warning: @Synthesize by Default will not synthesize a property declared in a protocol• If you use custom instance variable naming convention, enable this warning ( -Wobjc-missing-property-synthesis ) Pragma Night
  • 24. Core Data NSManagedObjectOpts out of synthesize by default /* NSManagedObject.h */ NS_REQUIRES_PROPERTY_DEFINITIONS @interface NSManagedObject : NSObject { • NSManagedObject synthesizes properties • Continue to use @property to declare typed accessors • Continue to use @dynamic to inhibit warnings Pragma Night
  • 25. NSNumbers Literals Pragma Night
  • 26. NSNumber CreationNSNumber *value;value = [NSNumber numberWithChar:X];value = [NSNumber numberWithInt:42];value = [NSNumber numberWithUnsignedLong:42ul];value = [NSNumber numberWithLongLong:42ll];value = [NSNumber numberWithFloat:0.42f];value = [NSNumber numberWithDouble:0.42];value = [NSNumber numberWithBool:YES]; Pragma Night
  • 27. NSNumber CreationNSNumber *value;value = @X;value = @42;value = @42ul;value = @42ll;value = @0.42f; Xcode 4.4+value = @0.42;value = @YES; Pragma Night
  • 28. Backward Compatibility !?#define YES (BOOL)1 // Before iOS 6, OSX 10.8#define YES ((BOOL)1) // After iOS 6, OSX 10.8Workarounds@(YES) // Use parentheses around BOOL Macros#if __IPHONE_OS_VERSION_MAX_ALLOWED < 60000#if __has_feature(objc_bool)#undef YES#undef NO // Redefine BOOL Macros#define YES __objc_yes#define NO __objc_no#endif#endif Pragma Night
  • 29. Boxed Expression Literals Pragma Night
  • 30. Boxed Expression LiteralsNSNumber *orientation = [NSNumber numberWithInt:UIDeviceOrientationPortrait];NSNumber *piOverSixteen = [NSNumber numberWithDouble:( M_PI / 16 )];NSNumber *parityDigit = [NSNumber numberWithChar:"EO"[i % 2]];NSString *path = [NSString stringWithUTF8String:getenv("PATH")];NSNumber *usesCompass = [NSNumber numberWithBool: [CLLocationManager headingAvailable]]; Pragma Night
  • 31. Boxed Expression LiteralsNSNumber *orientation = @( UIDeviceOrientationPortrait );NSNumber *piOverSixteen = @( M_PI / 16 );NSNumber *parityDigit = @( "OE"[i % 2] );NSString *path = @( getenv("PATH") ); Xcode 4.4+NSNumber *usesCompass = @( [CLLocationManager headingAvailable] ); Pragma Night
  • 32. Array Literals Pragma Night
  • 33. Array CreationMore choices, and more chances for errors NSArray *array; array = [NSArray array]; array = [NSArray arrayWithObject:a]; array = [NSArray arrayWithObjects:a, b, c, nil]; id objects[] = { a, b, c }; NSUInteger count = sizeof(objects) / sizeof(id); array = [NSArray arrayWithObjects:objects count:count]; Pragma Night
  • 34. Nil TerminationInconsistent behavior // if you write: id a = nil, b = @"hello", c = @42; NSArray *array = [NSArray arrayWithObjects:a, b, c, nil];Array will be empty // if you write: id objects[] = { nil, @"hello", @42 }; NSUInteger count = sizeof(objects)/ sizeof(id); NSArray *array = [NSArray arrayWithObjects:objects count:count];Exception: attempt to insert nil object from objects[0] Pragma Night
  • 35. Array CreationNSArray *array;array = [NSArray array];array = [NSArray arrayWithObject:a];array = [NSArray arrayWithObjects:a, b, c, nil];id objects[] = { a, b, c };NSUInteger count = sizeof(objects) / sizeof(id);array = [NSArray arrayWithObjects:objects count:count]; Pragma Night
  • 36. Array CreationNSArray *array;array = @[];array = @[ a ];array = @[ a, b, c ]; Xcode 4.4+array = @[ a, b, c ]; Pragma Night
  • 37. How Array Literals Work// when you write this:NSArray *array = @[ a, b, c ];// compiler generates:id objects[] = { a, b, c };NSUInteger count = sizeof(objects)/ sizeof(id);NSArray *array = [NSArray arrayWithObjects:objects count:count]; Pragma Night
  • 38. Dictionary Literals Pragma Night
  • 39. Dictionary CreationMore choices, and more chances for errors NSDictionary *dict; dict = [NSDictionary dictionary]; dict = [NSDictionary dictionaryWithObject:o1 forKey:k1]; dict = [NSDictionary dictionaryWithObjectsAndKeys: o1, k1, o2, k2, o3, k3, nil]; id objects[] = { o1, o2, o3 }; id keys[] = { k1, k2, k3 }; NSUInteger count = sizeof(objects) / sizeof(id); dict = [NSDictionary dictionaryWithObjects:objects forKeys:keys count:count]; Pragma Night
  • 40. Dictionary CreationNSDictionary *dict;dict = [NSDictionary dictionary];dict = [NSDictionary dictionaryWithObject:o1 forKey:k1];dict = [NSDictionary dictionaryWithObjectsAndKeys: o1, k1, o2, k2, o3, k3, nil];id objects[] = { o1, o2, o3 };id keys[] = { k1, k2, k3 };NSUInteger count = sizeof(objects) / sizeof(id);dict = [NSDictionary dictionaryWithObjects:objects forKeys:keys count:count]; Pragma Night
  • 41. Dictionary CreationNSDictionary *dict;dict = @{};dict = @{ k1 : o1 }; // key before objectdict = @{ k1 : o1, k2 : o2, k3 : o3 }; Xcode 4.4+dict = @{ k1 : o1, k2 : o2, k3 : o3 }; Pragma Night
  • 42. How Dictionary Literals Work// when you write this:NSDictionary *dict = @{ k1 : o1, k2 : o2, k3 : o3 };// compiler generates:id objects[] = { o1, o2, o3 };id keys[] = { k1, k2, k3 };NSUInteger count = sizeof(objects) / sizeof(id);NSDictionary *dict = [NSDictionary dictionaryWithObjects:objects orKeys:keys count:count]; Pragma Night
  • 43. Container Literals RestrictionAll containers are immutable, mutable use: -mutableCopy NSMutableArray *mutablePragmers = [@[ @"Fra", @"Giu", @"Mat", @"Max", @"Ste" ] mutableCopy];For constant containers, simply implement +initialize static NSArray *thePragmers; + (void)initialize { if (self == [MyClass class]) { thePragmers = @[ @"Fra", @"Giu", @"Mat", @"Max", @"Ste" ]; } } Pragma Night
  • 44. Object Subscripting Pragma Night
  • 45. Array SubscriptingNew syntax to access object at index: nsarray[index] @implementation SongList { NSMutableArray *_songs; } - (Song *)replaceSong:(Song *)newSong atIndex:(NSUInteger)idx { Song *oldSong = [_songs objectAtIndex:idx]; [_songs replaceObjectAtIndex:idx withObject:newSong]; return oldSong; } @end Pragma Night
  • 46. Array SubscriptingNew syntax to access object at index: nsarray[index] @implementation SongList { NSMutableArray *_songs; } - (Song *)replaceSong:(Song *)newSong atIndex:(NSUInteger)idx { Xcode 4.4+ Song *oldSong = _songs[idx]; _songs[idx] = newSong; return oldSong; } @end Pragma Night
  • 47. Dictionary SubscriptingNew syntax to access object by key: nsdictionary[key] @implementation Database { NSMutableDictionary *_storage; } - (id)replaceObject:(id)newObject forKey:(id <NSCopying>)key { id oldObject = [_storage objectForKey:key]; [_storage setObject:newObject forKey:key]; return oldObject; } @end Pragma Night
  • 48. Dictionary SubscriptingNew syntax to access object by key: nsdictionary[key] @implementation Database { NSMutableDictionary *_storage; } - (id)replaceObject:(id)newObject forKey:(id <NSCopying>)key { Xcode 4.4+ id oldObject = _storage[key]; _storage[key] = newObject; return oldObject; } @end Pragma Night
  • 49. How Subscripting Works iOS 6Array Style: Indexed subscripting methods OSX 10.8 - (elementType)objectAtIndexedSubscript:(indexType)idx - (void)setObject:(elementType)obj atIndexedSubscript:(indexType)idx;elementType must be an object pointer, indexType must be integral iOS 6Dictionary Style: Keyed subscripting methods OSX 10.8 - (elementType)objectForKeyedSubscript:(keyType)key; - (void)setObject:(elementType)obj forKeyedSubscript:(keyType)key;elementType and keyType must be an object pointer Pragma Night
  • 50. Indexed SubscriptingsetObject:atIndexedSubscript: @implementation SongList { NSMutableArray *_songs; } - (Song *)replaceSong:(Song *)newSong atIndex:(NSUInteger)idx { Song *oldSong = _songs[idx]; _songs[idx] = newSong; return oldSong; } @end Pragma Night
  • 51. Indexed SubscriptingsetObject:atIndexedSubscript: @implementation SongList { NSMutableArray *_songs; } - (Song *)replaceSong:(Song *)newSong atIndex:(NSUInteger)idx { Song *oldSong = _songs[idx]; [_songs setObject:newSong atIndexedSubscript:idx]; return oldSong; } @end Pragma Night
  • 52. Keyed SubscriptingsetObject:atIndexedSubscript: @implementation Database { NSMutableDictionary *_storage; } - (id)replaceObject:(id)newObject forKey:(id <NSCopying>)key { id oldObject = _storage[key]; _storage[key] = newObject; return oldObject; } @end Pragma Night
  • 53. Keyed SubscriptingsetObject:atIndexedSubscript: @implementation Database { NSMutableDictionary *_storage; } - (id)replaceObject:(id)newObject forKey:(id <NSCopying>)key { id oldObject = _storage[key]; [_storage setObject:newObject forKey:key]; return oldObject; } @end Pragma Night
  • 54. Backward Compatibility !?To deploy back to iOS 5 and iOS 4 you need ARCLite:use ARC or set explicit linker flag: “-fobjc-arc”To make compiler happy, you should add 4 categories: #if __IPHONE_OS_VERSION_MAX_ALLOWED < 60000 @interface NSDictionary(BCSubscripting) - (id)objectForKeyedSubscript:(id)key; @end @interface NSMutableDictionary(BCSubscripting) - (void)setObject:(id)obj forKeyedSubscript:(id )key; @end @interface NSArray(BCSubscripting) - (id)objectAtIndexedSubscript:(NSUInteger)idx; @end @interface NSMutableArray(BCSubscripting) - (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx; @end #endif Pragma Night
  • 55. Your Classes Can Be Subscriptable @interface SongList : NSObject - (Song *)objectAtIndexedSubscript:(NSUInteger)idx; - (void) setObject:(Song *)song atIndexedSubscript:(NSUInteger)idx; @end @implementation SongList { NSMutableArray *_songs; } - (Song *)objectAtIndexedSubscript:(NSUInteger)idx { return (Song *)_songs[idx]; } - (void) setObject:(Song *)song atIndexedSubscript:(NSUInteger)idx { _songs[idx] = song; } @end Pragma Night
  • 56. Summary Pragma Night
  • 57. Availability Feature Xcode 4.4+ iOS 6 OSX 10.8 Unordered Method Declarations ✓Enum With Fixed Underlying Type ✓ @Synthesize by Default ✓ NSNumbers Literals ✓ Boxed Expression Literals ✓ Array Literals ✓ Dictionary Literals ✓ Object Subscripting ✓ ✓* * Partially Required Pragma Night
  • 58. MigrationApple provides a migration tool which is build intoXcode: Edit Refactor Convert to Modern ... Pragma Night
  • 59. Demo Pragma Night
  • 60. Modern Objective-C References• Clang: Objective-C Literals• Apple: Programming with Objective-C• WWDC 2012 – Session 405 – Modern Objective-C• Mike Ash: Friday Q&A 2012-06-22: Objective-C Literals Pragma Night
  • 61. Modern Objective-C Books Pragma Night
  • 62. NSLog(@”Thank you!”); giuseppe.arici@pragmamark.org Pragma Night

×