SlideShare a Scribd company logo
Modern Objective-C
    Giuseppe Arici


     Pragma Night @ Talent Garden
It’s All About ...

Syntactic Sugar


                       Pragma Night
Unordered Method
  Declarations

               Pragma Night
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
Wrong Workaround
In 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
Okay Workaround 1
In 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
Okay Workaround 2
Reorder 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
Best Solution
Parse 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
Enum with Fixed
Underlying Type

                  Pragma Night
Enum with Indeterminate Type
Before OS X v10.5 and iOS
 typedef enum {
     NSNumberFormatterNoStyle,
     NSNumberFormatterDecimalStyle,
     NSNumberFormatterCurrencyStyle,
     NSNumberFormatterPercentStyle,
     NSNumberFormatterScientificStyle,
     NSNumberFormatterSpellOutStyle
 } NSNumberFormatterStyle;

 //typedef int NSNumberFormatterStyle;




                                         Pragma Night
Enum with Explicit Type
After 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
Enum with Fixed Underlying Type
LLVM 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
Enum with Fixed Underlying Type
NS_ENUM macro
 typedef NS_ENUM(NSUInteger, NSNumberFormatterStyle) {
     NSNumberFormatterNoStyle,
     NSNumberFormatterDecimalStyle,
     NSNumberFormatterCurrencyStyle,
     NSNumberFormatterPercentStyle,
     NSNumberFormatterScientificStyle,
     NSNumberFormatterSpellOutStyle
 };
                                                Xcode 4.4+

 •   Foundation declares like this



                                                         Pragma Night
Enum with Fixed Underlying Type
Stronger type checking (-Wenum-conversion)


 NSNumberFormatterStyle style = NSNumberFormatterRoundUp; // 3




warning:
implicit conversion from enumeration type 'enum
NSNumberFormatterRoundingMode' to different enumeration type
'NSNumberFormatterStyle' (aka 'enum NSNumberFormatterStyle')

                                                         Pragma Night
Enum with Fixed Underlying Type
Handling 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
@Synthesize by
   Default

                 Pragma Night
Properties Simplify Classes
@interface instance variables

 @interface Person : NSObject {
     NSString *_name;
 }
 @property(strong) NSString *name;
 @end

 @implementation Person




 @synthesize name = _name;

 @end



                                     Pragma Night
Properties Simplify Classes
@implementation instance variables

 @interface Person : NSObject


 @property(strong) NSString *name;
 @end

 @implementation Person {
     NSString *_name;
 }


 @synthesize name = _name;

 @end



                                     Pragma Night
Properties Simplify Classes
Synthesized instance variables

 @interface Person : NSObject


 @property(strong) NSString *name;
 @end

 @implementation Person




 @synthesize name = _name;

 @end



                                     Pragma Night
@Synthesize by Default
LLVM 4.2+ Compiler

 @interface Person : NSObject


 @property(strong) NSString *name;
 @end

 @implementation Person
                                     Xcode 4.4+


 @end



                                           Pragma Night
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 you'd written: @synthesize name = _name; */


 @end



                                                        Pragma Night
Backward Compatibility !?
Be careful, when in doubt be fully explicit

 @interface Person : NSObject


 @property(strong) NSString *name;
 @end

 @implementation Person




 @synthesize name;
 /* as if you'd written: @synthesize name = name; */
 @end



                                                       Pragma Night
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
Core Data NSManagedObject
Opts 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
NSNumbers Literals


                 Pragma Night
NSNumber Creation

NSNumber *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
NSNumber Creation

NSNumber *value;

value = @'X';

value = @42;

value = @42ul;

value = @42ll;

value = @0.42f;
                        Xcode 4.4+
value = @0.42;

value = @YES;




                              Pragma Night
Backward Compatibility !?
#define YES      (BOOL)1     // Before iOS 6, OSX 10.8


#define YES      ((BOOL)1) // After iOS 6, OSX 10.8


Workarounds
@(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
Boxed Expression
    Literals

                   Pragma Night
Boxed Expression Literals

NSNumber *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
Boxed Expression Literals

NSNumber *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
Array Literals


                 Pragma Night
Array Creation
More 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
Nil Termination
Inconsistent 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
Array Creation

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
Array Creation

NSArray *array;

array = @[];

array = @[ a ];

array = @[ a, b, c ];
                                   Xcode 4.4+
array = @[ a, b, c ];




                                         Pragma Night
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
Dictionary Literals


                      Pragma Night
Dictionary Creation
More 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
Dictionary Creation

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
Dictionary Creation

NSDictionary *dict;

dict = @{};

dict = @{ k1 : o1 }; // key before object

dict = @{ k1 : o1, k2 : o2, k3 : o3 };



                                            Xcode 4.4+
dict = @{ k1 : o1, k2 : o2, k3 : o3 };




                                                  Pragma Night
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
Container Literals Restriction
All 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
Object Subscripting


                  Pragma Night
Array Subscripting
New 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
Array Subscripting
New 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
Dictionary Subscripting
New 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
Dictionary Subscripting
New 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
How Subscripting Works
                                                              iOS 6
Array 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 6
Dictionary 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
Indexed Subscripting
setObject:atIndexedSubscript:

 @implementation SongList
 {
     NSMutableArray *_songs;
 }

 - (Song *)replaceSong:(Song *)newSong
               atIndex:(NSUInteger)idx
 {
     Song *oldSong = _songs[idx];
     _songs[idx] = newSong;
     return oldSong;
 }
 @end



                                         Pragma Night
Indexed Subscripting
setObject: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
Keyed Subscripting
setObject: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
Keyed Subscripting
setObject: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
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
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
Summary


          Pragma Night
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
Migration
Apple provides a migration tool which is build into
Xcode: Edit Refactor Convert to Modern ...




                                                 Pragma Night
Demo


       Pragma Night
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
Modern Objective-C Books




                       Pragma Night
NSLog(@”Thank you!”);




  giuseppe.arici@pragmamark.org

                                  Pragma Night

More Related Content

PDF
Modern Objective-C @ Pragma Night
PDF
Automatic Reference Counting @ Pragma Night
PDF
Ruby training day1
PPTX
MPI n OpenMP
PDF
2008 07-24 kwpm-threads_and_synchronization
PDF
Open mp library functions and environment variables
PDF
OpenMP Tutorial for Beginners
PDF
Open mp intro_01
Modern Objective-C @ Pragma Night
Automatic Reference Counting @ Pragma Night
Ruby training day1
MPI n OpenMP
2008 07-24 kwpm-threads_and_synchronization
Open mp library functions and environment variables
OpenMP Tutorial for Beginners
Open mp intro_01

What's hot (20)

ODP
Domain Specific Languages In Scala Duse3
PPTX
Intro to OpenMP
PDF
Objective-C Blocks and Grand Central Dispatch
PPTX
Parallelization using open mp
PPT
JavaScript - An Introduction
KEY
OpenMP
PDF
Ruby Programming Introduction
PDF
.Net Multithreading and Parallelization
PDF
RubyMotion Introduction
KEY
Know yourengines velocity2011
PDF
A Re-Introduction to JavaScript
PPTX
C++ Functions
PPT
OpenMP
KEY
Mirah Talk for Boulder Ruby Group
PPT
Lecture8
PDF
Introduction to Ruby
PPTX
Advance topics of C language
PDF
The Naked Bundle - Symfony Usergroup Belgium
PPTX
これからのPerlプロダクトのかたち(YAPC::Asia 2013)
PPTX
Shell scripting
Domain Specific Languages In Scala Duse3
Intro to OpenMP
Objective-C Blocks and Grand Central Dispatch
Parallelization using open mp
JavaScript - An Introduction
OpenMP
Ruby Programming Introduction
.Net Multithreading and Parallelization
RubyMotion Introduction
Know yourengines velocity2011
A Re-Introduction to JavaScript
C++ Functions
OpenMP
Mirah Talk for Boulder Ruby Group
Lecture8
Introduction to Ruby
Advance topics of C language
The Naked Bundle - Symfony Usergroup Belgium
これからのPerlプロダクトのかたち(YAPC::Asia 2013)
Shell scripting
Ad

Viewers also liked (9)

PDF
Automatic Reference Counting
PDF
iOS Api Client: soluzioni a confronto
PDF
Xcode - Just do it
PDF
Objective-C
PDF
Il gruppo Pragma mark
PDF
Automatic Reference Counting
PDF
iOS Ecosystem
PDF
Objective-C Blocks and Grand Central Dispatch
PDF
How to Become a Thought Leader in Your Niche
Automatic Reference Counting
iOS Api Client: soluzioni a confronto
Xcode - Just do it
Objective-C
Il gruppo Pragma mark
Automatic Reference Counting
iOS Ecosystem
Objective-C Blocks and Grand Central Dispatch
How to Become a Thought Leader in Your Niche
Ad

Similar to Modern Objective-C (20)

PDF
201005 accelerometer and core Location
PDF
Session 5 - Foundation framework
PDF
Iphone course 1
PDF
Taking Objective-C to the next level. UA Mobile 2016.
PDF
What Makes Objective C Dynamic?
KEY
Runtime
PDF
The messy lecture
PPTX
iOS Session-2
ZIP
KEY
Objective-C: a gentle introduction
PDF
iOS 5 & Xcode 4: ARC, Stroryboards
KEY
iPhone Development Intro
PDF
Никита Корчагин - Programming Apple iOS with Objective-C
PPT
iOS Application Development
PDF
Session 2 - Objective-C basics
PDF
iOS Programming Intro
ODP
A quick and dirty intro to objective c
PDF
Louis Loizides iOS Programming Introduction
PPTX
Presentation 3rd
PDF
Write native iPhone applications using Eclipse CDT
201005 accelerometer and core Location
Session 5 - Foundation framework
Iphone course 1
Taking Objective-C to the next level. UA Mobile 2016.
What Makes Objective C Dynamic?
Runtime
The messy lecture
iOS Session-2
Objective-C: a gentle introduction
iOS 5 & Xcode 4: ARC, Stroryboards
iPhone Development Intro
Никита Корчагин - Programming Apple iOS with Objective-C
iOS Application Development
Session 2 - Objective-C basics
iOS Programming Intro
A quick and dirty intro to objective c
Louis Loizides iOS Programming Introduction
Presentation 3rd
Write native iPhone applications using Eclipse CDT

Recently uploaded (20)

PPTX
A Presentation on Artificial Intelligence
PDF
A comparative analysis of optical character recognition models for extracting...
PDF
Univ-Connecticut-ChatGPT-Presentaion.pdf
PDF
gpt5_lecture_notes_comprehensive_20250812015547.pdf
PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
A novel scalable deep ensemble learning framework for big data classification...
PDF
August Patch Tuesday
PPTX
OMC Textile Division Presentation 2021.pptx
PDF
ENT215_Completing-a-large-scale-migration-and-modernization-with-AWS.pdf
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
Accuracy of neural networks in brain wave diagnosis of schizophrenia
PDF
Web App vs Mobile App What Should You Build First.pdf
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PPTX
TechTalks-8-2019-Service-Management-ITIL-Refresh-ITIL-4-Framework-Supports-Ou...
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
WOOl fibre morphology and structure.pdf for textiles
PDF
Microsoft Solutions Partner Drive Digital Transformation with D365.pdf
PDF
Assigned Numbers - 2025 - Bluetooth® Document
PDF
Hybrid model detection and classification of lung cancer
PDF
From MVP to Full-Scale Product A Startup’s Software Journey.pdf
A Presentation on Artificial Intelligence
A comparative analysis of optical character recognition models for extracting...
Univ-Connecticut-ChatGPT-Presentaion.pdf
gpt5_lecture_notes_comprehensive_20250812015547.pdf
Programs and apps: productivity, graphics, security and other tools
A novel scalable deep ensemble learning framework for big data classification...
August Patch Tuesday
OMC Textile Division Presentation 2021.pptx
ENT215_Completing-a-large-scale-migration-and-modernization-with-AWS.pdf
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Accuracy of neural networks in brain wave diagnosis of schizophrenia
Web App vs Mobile App What Should You Build First.pdf
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
TechTalks-8-2019-Service-Management-ITIL-Refresh-ITIL-4-Framework-Supports-Ou...
Encapsulation_ Review paper, used for researhc scholars
WOOl fibre morphology and structure.pdf for textiles
Microsoft Solutions Partner Drive Digital Transformation with D365.pdf
Assigned Numbers - 2025 - Bluetooth® Document
Hybrid model detection and classification of lung cancer
From MVP to Full-Scale Product A Startup’s Software Journey.pdf

Modern Objective-C

  • 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 Workaround In 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 1 In 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 2 Reorder 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 Solution Parse 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 Fixed Underlying Type Pragma Night
  • 10. Enum with Indeterminate Type Before OS X v10.5 and iOS typedef enum { NSNumberFormatterNoStyle, NSNumberFormatterDecimalStyle, NSNumberFormatterCurrencyStyle, NSNumberFormatterPercentStyle, NSNumberFormatterScientificStyle, NSNumberFormatterSpellOutStyle } NSNumberFormatterStyle; //typedef int NSNumberFormatterStyle; Pragma Night
  • 11. Enum with Explicit Type After 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 Type LLVM 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 Type NS_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 Type Stronger type checking (-Wenum-conversion) NSNumberFormatterStyle style = NSNumberFormatterRoundUp; // 3 warning: implicit conversion from enumeration type 'enum NSNumberFormatterRoundingMode' to different enumeration type 'NSNumberFormatterStyle' (aka 'enum NSNumberFormatterStyle') Pragma Night
  • 15. Enum with Fixed Underlying Type Handling 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 Classes Synthesized instance variables @interface Person : NSObject @property(strong) NSString *name; @end @implementation Person @synthesize name = _name; @end Pragma Night
  • 20. @Synthesize by Default LLVM 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 you'd 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 you'd 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 NSManagedObject Opts 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 Creation NSNumber *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 Creation NSNumber *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.8 Workarounds @(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 Literals NSNumber *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 Literals NSNumber *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 Creation More 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 Termination Inconsistent 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 Creation 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
  • 36. Array Creation NSArray *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 Creation More 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 Creation 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
  • 41. Dictionary Creation NSDictionary *dict; dict = @{}; dict = @{ k1 : o1 }; // key before object dict = @{ 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 Restriction All 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 Subscripting New 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 Subscripting New 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 Subscripting New 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 Subscripting New 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 6 Array 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 6 Dictionary 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 Subscripting setObject: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 Subscripting setObject: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 Subscripting setObject: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 Subscripting setObject: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. Migration Apple provides a migration tool which is build into Xcode: 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