Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

download Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

of 30

Transcript of Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    1/30

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    2/30

    2 of 30

    Commenting

    Comments should be used to organize code and to provide extra information for future refactoring or for other developers whomight be reading your code. Comments are ignored by the compiler so they do not increase the compiled program size.

    Two ways of commenting:

    Using pragma to organize your code:

    Back to top

    Data Types

    Size

    Permissible sizes of data types are determined by how many bytes of memory are allocated for that specific type and whether it'sa 32-bit or 64-bit environment. In a 32-bit environment, long is given 4 bytes, which equates to a total range of 2^(4*8) (with 8bits in a byte) or 4294967295 . In a 64-bit environment, long is given 8 bytes, which equates to 2^(8*8) or 1.84467440737096e19 .

    For a complete guide to 64-bit changes, please see the transition document(https://developer.apple.com/library/mac/documentation/Darwin/Conceptual/64bitPorting/transition/transition.html#//apple_ref/doc/uid/TP40001064-CH207-

    TPXREF101).

    C Primitives

    Note: Objective-C inherits all of the C language primitive types and then adds a few extras.

    Void

    void is C's empty data type. It is most commonly used to specify the return type for functions that don't return anything.

    Integers

    Integers can be signed or unsigned. When signed, they can be either positive or negative and when unsigned, they can only bepositive. Example: When declaring an unsigned int , the range of allowable integer values for a 32-bit compiler will shift from -2147483648 to +2147483647 to instead be 0 to +4294967295.

    Integer types with their accompanying byte sizes:

    // This is an inline comment

    /* This is a block comment

    and it can span multiple lines. */

    // You can also use it to comment out code

    /*

    - (SomeOtherClass *)doWork

    {

    // Implement this

    }

    */

    # p r a g m a m a r k - U s e p r a g m a m a r k t o l o g i c a l l y o rg a n i z e y o u r c o d e #pragma mark - Use p ragma mark to log ica l ly o rgan ize your code

    // Declare some methods or variables here

    #pragma mark - They a l so show up n ice ly in the p roper t i e s /me thods l i s t i n Xcode #pragma mark - They a l so show up n ice ly in the p roper t i e s /me thods l i s t i n Xcode

    // Declare some more methods or variables here

    // Char (1 byte for both 32-bit and 64-bit)

    uns igneduns igned cha rc h a r anUnsignedChar = = 255 ;

    NSLog( @"char size: %zu" , s i zeofs i z e o f ( cha rc h a r ));

    // Short (2 bytes for both 32-bit and 64-bit)

    s h o r ts h o r t aShort = = -- 32768 ;

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    3/30

    3 of 30

    Fixed width integer types with their accompanying byte sizes as the variable names:

    Floating Point

    Floats cannot be signed or unsigned.

    Objective-C Primitives

    id : Known as the anonymous or dynamic object type, it can store a reference to any type of object with no need to specify apointer symbol.

    uns igneduns igned s h o r ts h o r t anUnsignedShort = = 65535 ;

    NSLog( @"short size: %zu" , s i zeofs i z e o f ( s h o r ts h o r t ));

    // Integer (4 bytes for both 32-bit and 64-bit)

    in tin t anInt = = -- 2147483648 ;

    uns igneduns igned in ti n t anUnsignedInt = = 4294967295 ;

    NSLog( @"int size: %zu" , s i zeofs i z e o f ( in tin t ));

    // Long (4 bytes for 32-bit, 8 bytes for 64-bit)

    longlong aLong = = -- 9223372036854775808 ; // 32-bit

    uns igneduns igned longl o n g anUnsignedLong = = 18446744073709551615 ; // 32-bit

    NSLog( @"long size: %zu" , s i zeofs i z e o f ( longl o n g ));

    // Long Long (8 bytes for both 32-bit and 64-bit)

    longlong longlong aLongLong = = -- 9223372036854775808 ;

    uns igneduns igned longl o n g longl o n g anUnsignedLongLong = = 18446744073709551615 ;

    NSLog( @"long long size: %zu" , s i zeofs i z e o f ( l o n glong l o n glong ));

    // Exact integer types

    in t8_ tin t8_ t aOneByteInt = = 127 ;

    u i n t 8 _ tu i n t 8 _ t aOneByteUnsignedInt = = 255 ;

    i n t 1 6 _ ti n t 1 6 _ t aTwoByteInt = = 32767 ;

    u in t16_ tu in t16_ t aTwoByteUnsignedInt = = 65535 ;i n t 3 2 _ ti n t 3 2 _ t aFourByteInt = = 2147483647 ;

    u in t32_ tu in t32_ t aFourByteUnsignedInt = = 4294967295 ;

    i n t 6 4 _ ti n t 6 4 _ t anEightByteInt = = 9223372036854775807 ;

    u in t64_ tu in t64_ t anEightByteUnsignedInt = = 18446744073709551615 ;

    // Minimum integer types

    in t_ leas t8_ tin t_ leas t8_ t aTinyInt = = 127 ;

    u i n t _ l e a s t 8 _ tu in t_ leas t8_ t aTinyUnsignedInt = = 255 ;

    i n t _ l e a s t 1 6 _ tin t_ leas t16_ t aMediumInt = = 32767 ;

    u in t_ leas t16_ tu in t_ leas t16_ t aMediumUnsignedInt = = 65535 ;

    i n t _ l e a s t 3 2 _ tin t_ leas t32_ t aNormalInt = = 2147483647 ;

    u in t_ leas t32_ tu in t_ leas t32_ t aNormalUnsignedInt = = 4294967295 ;

    i n t _ l e a s t 6 4 _ tin t_ leas t64_ t aBigInt = = 9223372036854775807 ;

    u in t_ leas t64_ tu in t_ leas t64_ t aBigUnsignedInt = = 18446744073709551615 ;

    // The largest supported integer type

    in tmax_ tin tmax_ t theBiggestInt = = 9223372036854775807 ;

    u i n t m a x _ tu i n t m a x _ t theBiggestUnsignedInt = = 18446744073709551615 ;

    // Single precision floating-point (4 bytes for both 32-bit and 64-bit)

    f l o a tf l o a t aFloat = = 72.0345f ;

    NSLog( @"float size: %zu" , s i zeofs i z e o f ( f l o a tf l o a t ));

    // Double precision floating-point (8 bytes for both 32-bit and 64-bit)

    doub ledoub le aDouble = = -- 72.0345f ;

    NSLog( @"double size: %zu" , s i zeofs i z e o f ( doub led o u b l e ));

    // Extended precision floating-point (16 bytes for both 32-bit and 64-bit)

    longlong doub ledoub le aLongDouble = = 72.0345e7L ;

    NSLog( @"long double size: %zu" , s i zeofs i z e o f ( l o n glong doub ledoub le ));

    idid delegate = = self.delegate;

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    4/30

    4 of 30

    Class : Used to denote an object's class and can be used for introspection of objects.

    Method : Used to denote a method and can be used for swizzling methods.

    SEL : Used to specify a selector which is compiler-assigned code that identifies a method name.

    IMP : Used to point to the memory address of the start of a method. You will probably never need to use this.

    BOOL : Used to specify a boolean type where 0 is considered NO (false) and any non-zero value is considered YES (true). Any nilobject is also considered to be NO so there is no need to perform an equality check with nil (e.g. just write if (someObject) not if(someObject != nil) ).

    nil : Used to specify a null object pointer. When classes are first initialized, all properties of the class are set to 0 which meansthey point to nil .

    Objective-C also has a number of other types such as NSInteger , NSUInteger , CGRect , CGFloat , CGSize , CGPoint , etc.

    Enum & Bitmask Types

    Enumeration types can be defined a number of different ways:

    C l a s sC l a s s aClass = = [UIView class];

    Method aMethod = = class_getInstanceMethod(aClass, aSelector);

    SE LSE L someSelector = = @ s e l e c t o r@selector(someMethodName);

    IM PIM P theImplementation = = [self methodForSelector: : someSelector];

    // Boolean

    BOOLBOOL isBool = = YES; // Or NO

    // Specifying a typed enum with a name (recommended way)

    t y p e d e ft y p e d e f N S _ E N U MN S _ E N U M(NSInteger, UITableViewCellStyle) {

    UITableViewCellStyleDefault,

    UITableViewCellStyleValue1, UITableViewCellStyleValue2,

    UITableViewCellStyleSubtitle

    };

    // Specify a bitmask with a name (recommended way)

    t y p e d e ft y p e d e f N S _ O P T I O N SNS_OPTIONS (NSUInteger, RPBitMask) {

    RPOptionNone = = 0,

    RPOptionRight = = 1 <

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    5/30

    5 of 30

    Working with Bitmasks

    Casting to Data Types

    Sometimes it is necessary to cast an id or different type into a specific class or data type. Examples of this would be casting from afloat to an int or from a UITableViewCell to a subclass such as RPTableViewCell .

    Casting non-object data types:

    Casting object data types:

    Back to top

    ConstantsUsing const is usually the better approach since const points to the same memory address for any references to that item in code.#define defines a macro which replaces all references with the actual constant value contents before compilation starts, insteadof being a memory pointer to that constant value.

    Constants can be defined as:

    To make the constant available to external classes, you must also add it to the header .h file:

    If you know that a constant will only be available within it's containing implementation .m file, specify it as:

    A static variable declared within a method retains its value between invocations. This can be useful when declaring a singleton orcreating custom setters/getters for a property.

    Back to top

    Operators

    // Set bits (only valid if it makes sense that your status may have many of the bitmask values)

    RPBitMask status = = RPOptionNone;

    status |= |= RPOptionBottom;

    status != != RPOptionTop;

    // Toggle bit

    status ^= ^= RPOptionTop;

    // Set single bit to zero

    status &=& = !! RPOptionBottom;

    // Check if it matches a certain bit

    i fif (status & & RPOptionTop) {

    [self doSometing];

    }

    // Format: nonObjectType variableName = (nonObjectType)variableNameToCastFrom;

    in tin t anInt = = ( i n tin t )anAnonymouslyTypedNonObjectOrDifferentDataType;

    // Format: ClassNameOrObjectType *variableName = (ClassNameOrObjectType *)variableNameToCastFrom;

    UIViewController * * aViewController = = (UIViewController * * )anAnonymouslyTypedObjectOrDifferentDataType;

    // Format: type const constantName = value;

    NSString * * c o n s tco ns t kRPShortDateFormat = = @"MM/dd/yyyy" ;

    // Format: #define constantName value

    #def ine kRPShor tDa teFormat @"MM/dd/yyyy" #def ine kRPShor tDa teFormat @"MM/dd/yyyy"

    ex te rnext ern NSString * * c o n s tco ns t kRPShortDateFormat;

    s t a t i csta tic NSString * * c o n s tco ns t kRPShortDateFormat = = @"MM/dd/yyyy" ;

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    6/30

    6 of 30

    Arithmetic Operators

    Operator Purpose

    + Addition

    - Subtraction

    * Multiplication

    / Division

    % Modulo

    Relational and Equality Operators

    Operator Purpose

    == Equal to

    != Not equal to

    > Greater than

    < Less than

    >= Greater than or equal to

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    7/30

    7 of 30

    Operator Purpose

    Increment and Decrement Operators

    Operator Purpose

    ++ Addition

    -- Subtraction

    *= Multiplication/= Division

    %= Modulo

    &= Bitwise AND

    |= Bitwise Inclusive OR

    ^= Exclusive OR

    = Shift Right

    Bitwise Operators

    Operator Purpose

    & Bitwise AND

    | Bitwise Inclusive OR

    ^ Exclusive OR

    ~ Unary complement (bit inversion)

    > Shift Right

    Other operators

    Operator Purpose

    () Cast

    ? : Conditional

    & Memory Address

    * Pointer

    Back to top

    Declaring Classes

    Classes are declared using two files: a header ( .h ) file and an implementation ( .m ) file.

    The header file should contain (in this order):

    Any needed #import statements or forward @class declarations

    Any protocol declarations

    An @interface declaration specifying which class you're inheriting from

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    8/30

    8 of 30

    All publicly accessible variables, properties and methods

    The implementation file should contain (in this order):

    Any needed #import statements

    An anonymous category, or class extension, for any private variables or properties

    An @implementation declaration specifying the class

    All public and private methods

    Example:

    MyClass.h

    MyClass.m

    # impor t "SomeClass .h" # impor t "SomeClass .h"

    // Used instead of #import to forward declare a class in property return types, etc.

    @class@ c l a s s SomeOtherClassS o m e O t h e r C l a s s ;

    // Place all global constants at the top

    ex te rnext ern NSString * * c o n s tconst kRPErrorDomain;

    // Format: YourClassName : ClassThatYouAreInheritingFrom

    @in te r face@ i n t e r f a c e M y C l a s sM y C l a s s : S o m e C l a s sS o m e C l a s s

    // Public properties first

    @ p r o p e r t y@p ro pe rt y (readonly, nonatomic, strong) SomeClass * *someProperty;

    // Then class methods

    ++ ( i did ) s o m e C l a s s M e t h o ds o m e C l a s s M e t h o d ;

    // Then instance methods

    -- (SomeOtherClass * * ) d o Wo r kd o Wo r k ;

    @end@end

    #impor t "MyClass .h" # impor t "MyClass .h" # impor t "SomeOtherClass .h" # impor t "SomeOtherClass .h"

    // Declare any constants at the top

    NSString * * c o n s tconst kRPErrorDomain = = @"com.myIncredibleApp.errors" ;

    s t a t i csta tic NSString * * c o n s tco ns t kRPShortDateFormat = = @"MM/dd/yyyy" ;

    // Class extensions for private variables / properties

    @in te r face@ i n t e r f a c e M y C l a s sM y C l a s s ()

    {

    in ti n t somePrivateInt;

    }

    // Re-declare as a private read-write version of the public read-only property

    @ p r o p e r t y@p ro pe rt y (readwrite, nonatomic, strong) SomeClass * *someProperty;

    @end@end

    @ i m p l e m e n t a t i o n@ i m p l e m e n t a t i o n M y C l a s sM y C l a s s

    // Use #pragma mark - statements to logically organize your code

    # p r a g m a m a r k - C l a s s M e t h o d s #pragma mark - C lass Methods

    ++ ( i did ) s o m e C l a s s M e t h o ds o m e C l a s s M e t h o d

    {

    re tu rnre tu rn [[MyClass alloc] init];

    }

    # p r a g m a m a r k - I n i t & D e a l l o c m e t h o d s #pragma mark - In i t & Dea l loc me thods

    -- ( i did ) i n i tin i t

    {

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    9/30

    9 of 30

    Instantiation

    When you want to create a new instance of a class, you use the syntax:

    The alloc class method returns a pointer to a newly allocated block of memory large enough to store an instance of the class. Theallocated memory contains zeros except for one instance variable, isa , that all Objective-C objects are required to have. The isavariable is automatically initialized to point to the class object that allocated the memory and enables the instance to receivemessages such as init that are used to complete initialization.

    Back to top

    Preprocessor Directives

    This section needs a lot of love, so please feel free to improve upon it!

    Directive Purpose

    #define Used to define constants or macros that are replaced by the compiler at runtime

    #elif An else if conditional statement

    #else An else conditional statement

    #endif An end if conditional statement#error Used to flag an error line in code

    #if An if conditional statement

    #ifdef An if defined conditional statement

    #ifndef An if not defined conditional statement

    #import Imports a header file. This directive is identical to #include , except that it won't include the same file more thanonce

    #include Includes a header file

    i fif (self = = [super init]) {

    // Initialize any properties or setup code here

    }

    r e tu rnretu rn self;

    }

    // Dealloc method should always follow init method

    -- ( v o i dvo id ) d e a l l o cd e a l l o c

    {

    // Remove any observers or free any necessary cache, etc.

    [super dealloc];

    }

    # p r a g m a m a r k - I n s t a n c e M e t h o d s #pragma mark - Ins t ance Methods

    -- (SomeOtherClass * * ) d o Wo r kd o Wo r k

    {

    // Implement this

    }

    @end@end

    MyClass * * myClass = = [[MyClass alloc] init];

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    10/30

    10 of 30

    #pragma Used for commenting code or inhibiting compiler warnings

    #undef Used to undefine and redefine macros

    #warning Used to flag a warning line in code

    Directive Purpose

    Special operator

    The special operator defined is used in #if and #elif expressions to test whether a certain name is defined as a macro.

    defined is useful when you wish to test more than one macro for existence at once. For example, #if defined(__IPHONE_8_0) ||defined(__MAC_10_9) would succeed if either of the names __IPHONE_8_0 or __MAC_10_9 is defined as a macro.

    Back to top

    Compiler Directives

    Also see the literals section.

    Classes and Protocols

    Directive Purpose

    @class Declares the names of classes defined elsewhere

    @interface Begins the declaration of a class or category interface

    @implementation Begins the definition of a class or category

    @protocol Begins the declaration of a formal protocol

    @required Declares the methods following the directive as required (default)

    @optionalDeclares the methods following the directive as optional. Classes implementing this protocol can decidewhether to implement an optional method or not and should first check if the method is implementedbefore sending it a message.

    @end Ends the declaration/definition of a class, category, or protocol

    Properties

    Directive Purpose

    @property Declares a property with a backing instance variable

    @synthesize Synthesizes a property and allows the compiler to generate setters/getters for the backing instance variable

    @dynamic Tells the compiler that the setter/getter methods are not implemented by the class itself but somewhere else,

    like the superclass

    Errors

    Directive Purpose

    @throw Throws an exception

    @try Specifies a block of code to attempt

    @catch Specifies what to do if an exception was thrown in the @try block

    @finally Specifies code that runs whether an exception occurred or not

    Visibility of Instance Variables

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    11/30

    11 of 30

    Directive Purpose

    @private Limits the scope of instance variables specified below it to the class that declares it

    @protected Limits the scope of instance variables specified below it to declaring and inheriting classes

    @public Removes restrictions on the scope of instance variables specified below it

    @package Declares the instance variables following the directive as public inside the framework that defined the class, butprivate outside the framework (64-bit only)

    Directive Purpose

    The default is @protected , so there is no need to explicitly specify this.

    Others

    Directive Purpose

    @selector(method) Returns the compiled selector that identifies a method

    @protocol(name) Returns the given protocol (an instance of the Protocol class)

    @synchronized Encapsulates code in a mutex lock to ensure that the block of code and the locked object can only beaccessed by one thread at a time

    @autoreleasepool Replaces (and is 6 times faster than) the NSAutoreleasePool class

    @encode(spec) Yields a character string that encodes the type structure of spec

    @compatibility_alias Allows you to define an alias name for an existing class.

    @defs(classname) Yields the internal data structure of classname instances

    @import Imports a module and autolinks its framework (currently for Apple frameworks only)

    Back to top

    Literals

    Literals are compiler directives which provide a shorthand notation for creating common objects.

    Syntax What it does

    @"string" Returns an NSString object

    @28, @3.14, @YES Returns an NSNumber object initialized with an appropriate class constructor, depending on the type

    @[] Returns an NSArray object

    @{} Returns an NSDictionary object

    @() Dynamically evaluates the boxed expression and returns the appropriate object literal based on its value

    NSArray Access Syntax

    NSDictionary Access Syntax

    NSArray * * example = = @[ @"hi" , @"there" , @23, @ YES ];

    NSLog( @"item at index 0: %@" , example[ 0 ]);

    NSDictionary * *example = = @{ @"hi" :: @"there" , @"iOS" :: @"people" };

    NSLog( @"hi %@" , example[ @"hi" ]);

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    12/30

    12 of 30

    Caveats

    Similar to NSString literals, collection objects made via literal arrays and dictionaries are immutable. Instead, you will have tomake a mutable copy after making the immutable dictionary or array. Additionally, you cannot have static initializers like you canwith NSString .

    Back to top

    Methods

    Declaration Syntax

    For methods without a return type, use void :

    + precedes declarations of class methods:

    - precedes declarations of class instance methods:

    Method arguments are declared after colons : and the method signature should describe the argument type:

    Argument and return types are declared using type casting syntax:

    Calling Methods

    Methods are called using bracket syntax: [self someMethod]; or [self sometMethodWithObject:object];

    self is a reference to the method's containing class. The self variable is present in all Objective-C methods and it is one of twohidden arguments passed to code that implements a method, the other being _cmd , which identifies the received message.

    At times, it is necessary to call a method in the superclass using [super someMethod]; .

    Under the hood, methods are implemented via message sending and they are turned into a variation of one of these two Cfunctions:

    Testing Selectors

    If you'd like to test if a class responds to a certain selector before you send it (and possibly crash), you can do so with:

    This pattern is common when you have a delegate implemented and need to test for methods declared as @optional before callingthem on the delegate object.

    Back to top

    // Does not return anything or take any arguments

    -- ( v o i dvo id ) someMethodsomeMethod ;

    // Call on a class (e.g. [MyClass someClassMethod]);

    ++ ( v o i dvo id ) s o m e C l a s s M e t h o ds o m e C l a s s M e t h o d ;

    // Called on an instance of a class (e.g. [[NSString alloc] init]);

    -- ( v o i dvo id ) s o m e C l a s s I n s t a n c e M e t h o dsomeClass Ins tanceMethod ;

    // Does something with an NSObject argument

    -- ( v o i dvo id ) d o Wo r k Wi t h O b j e c t :doWorkWi thObjec t : (NSObject * * ) object ;

    // Returns an NSString object for the given NSObject arguments

    -- (NSString * * ) s t r i n g F r o m O b j e c t :s t r ingFromObjec t : (NSObject * * ) object a n d S o m e O t h e r O b j e c t :andSomeOtherObjec t : (NSObject * * ) otherObject ;

    idid ob jc_msgSendob jc_msgSend ( i di d self, SE LSE L op, ...);

    i did ob jc_msgSendSuperob jc_msgSendSuper ( s t ruc tstr uct objc_super * *super, SE LS EL op, ...);

    i fif ([someClassOrInstance respondsToSelector: : @ s e l e c t o r@selector(someMethodName)])

    {

    // Call the selector or do something here

    }

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    13/30

    13 of 30

    Properties and Variables

    Declaring a property allows you to maintain a reference to an object within a class or to pass objects between classes.

    Public properties are declared in the header ( .h ) file:

    Private properties are declared in an anonymous category, or class extension, in the implementation ( .m ) file:

    The LLVM compiler automatically synthesizes all properties so there is no longer a need to explicitly write @synthesizestatements for properties anymore. When a property is synthesized, accessors are created which allow you to set and get thevalue of a property.

    Even though you may not see them since they are created at build time, a getter/setter pair can be shown as:

    You can overrride the getter and setter of a property to create customized behavior, or even use this pattern to create transientproperties such as:

    Properties are typically backed by an instance variable with a leading underscore, so creating a property called firstName wouldhave a backing instance variable with the name _firstName . You should only access that private instance variable if you overridethe getter/setter or if you need to setup the ivar in the class init method.

    Property Attributes

    When a property is specified, it is given the syntax:

    @inte r face@ i n t e r f a c e M y C l a s sM y C l a s s : NSObjec tN S O b j e c t

    @ p r o p e r t y@p ro pe rt y (readonly, nonatomic, strong) NSString * *fullName;

    @end@end

    #impor t "MyClass .h" # impor t "MyClass .h"

    // Class extension for private variables / properties

    @in te r face@ i n t e r f a c e M y C l a s sM y C l a s s ()

    {

    // Instance variable

    in ti n t somePrivateInteger;

    }

    // Private properties

    @ p r o p e r t y@property (nonatomic, strong) NSString * *firstName;@ p r o p e r t y@property (nonatomic, strong) NSString * *lastName;

    @ p r o p e r t y@p ro pe rt y (readwrite, nonatomic, strong) NSString * *fullName;

    @end@end

    @ i m p l e m e n t a t i o n@ i m p l e m e n t a t i o n M y C l a s sM y C l a s s

    // Class implementation goes here

    @end@end

    -- ( B O O LBOOL) f in i shedf in i shed

    {

    re tu rnret urn _finished;

    }

    -- ( v o i dvo id ) se tF in i shed :se tF in i shed : ( BOOLB O O L) aValue

    {

    _finished = = aValue;

    }

    -- (NSString * * ) fu l lNamefu l lName

    {

    re tu rnre tu rn [NSString stringWithFormat: : @"%@ %@", self.firstName, self.lastName];

    }

    @ p r o p e r t y@property SomeClass * *someProperty;

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    14/30

    14 of 30

    where xxx can be a combination of:

    Type What it does

    copy

    Creates an immutable copy of the object upon assignment and is typically used for creating animmutable version of a mutable object. Use this if you need the value of the object as it is at this

    moment, and you don't want that value to reflect any future changes made by other owners of theobject.

    assign Generates a setter which assigns the value directly to the instance variable, rather than copying orretaining it. This is typically used for creating properties for primitive types ( float , int , BOOL, etc).

    weak

    Variables that are weak can still point to objects but they do not become owners (or increase the retaincount by 1). If the object's retain count drops to 0, the object will be deallocated from memory and theweak pointer will be set to nil . It's best practice to create all delegates and IBOutlet 's as weak referencessince you do not own them.

    unsafe_unretainedAn unsafe reference is similar to a weak reference in that it doesn't keep its related object alive, but itwon’t be set to nil if the object is deallocated. This can lead to crashes due to accessing that deallocated

    object and therefore you should use weak unless the OS or class does not support it.

    strongThis is the default and is required when the attribute is a pointer to an object. The automatically generated setter will retain (i.e. increment the retain count of) the object and keep the object alive untilreleased.

    readonly This only generates a getter method so it won't allow the property to be changed via the setter method.

    readwriteThis is the default and generates both a setter and a getter for the property. Often times, a readonlyproperty will be publicly defined and then a readwrite for the same property name will be privately redefined to allow mutation of the property value within that class only.

    atomic This is the default and means that any access operation is guaranteed to be uninterrupted by anotherthread and is typically slower in performance to use.

    nonatomic This is used to provide quicker (but thus interruptable) access operations.

    getter=method Used to specify a different name for the property's getter method. This is typically done for booleanproperties (e.g. getter=isFinished )

    setter=method Used to specify a different name for the property's setter method. (e.g. setter=setProjectAsFinished )

    Accessing Properties

    Properties can be accessed using either bracket syntax or dot notation, with dot notation being cleaner to read.

    Local Variables

    Local variables exist only within the scope of a method.

    Back to top

    // Or

    @ p r o p e r t y@pr ope rty (xxx) SomeClass * *someProperty;

    [self myProperty];

    // Or

    self.myProperty

    -- ( v o i dvo id ) doWorkdoWork

    {

    NSString * *localStringVariable = = @"Some local string variable." ;

    [self doSomethingWithString: : localStringVariable];

    }

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    15/30

    15 of 30

    Naming Conventions

    The general rule of thumb: Clarity and brevity are both important, but clarity should never be sacrificed for brevity.

    Methods and Properties

    These both use camelCase where the first letter of the first word is lowercase and the first letter of each additional word iscapitalized.

    Class names and Protocols

    These both use CapitalCase where the first letter of every word is capitalized.

    Methods

    These should use verbs if they perform some action (e.g. performInBackground ). You should be able to infer what is happening,what arguments a method takes, or what is being returned just by reading a method signature.

    Example:

    Properties and Local Variables

    When using properties, instance variables are internally created with a preceeding underscore, so myVariableName is created as_myVariableName . However, Objective-C now synthesizes these properties for you so you should never have to access thatunderscored instance variable directly except in a custom setter.

    Instead, instance variables should always be accessed and mutated using self.

    Local variables should not contain underscores.

    Constants

    These should start with k and XXX where XXX is a prefix, possibly your initials, to avoid naming conflicts. You should not be afraidto be expressive with your constant naming, especially if it's a global constant. Using kRPNavigationFadeOutAnimationDuration ismuch better than fadeOutTiming .

    Back to top

    BlocksBlocks are essentially anonymous functions that are used to pass arbitrary code between methods or to execute code as a callback within a method. Since blocks are implemented as closures, the surrounding state is also captured (which can sometimes lead toretain cycles).

    Syntax

    // Correct

    -- (UITableViewCell * * ) t a b l e Vi e w :tab leView: (UITableView * * ) tableView ce l lForRowAtIndexPa th :ce l lForRowAtIndexPa th : (NSIndexPath * * ) indexPath

    {

    // Code

    }

    // Incorrect (not expressive enough)

    -- (UITableViewCell * * ) t a b l e :t ab le : (UITableView * * ) tableView c e l l :c e l l : (NSIndexPath * * ) indexPath

    {

    // Code

    }

    // As a local variable

    returnType (^ ^blockName)(parameterTypes) = = ^̂ returnType(parameters) {

    // Block code here

    };

    // As a property

    @ p r o p e r t y@property (nonatomic, copy) returnType (^ ^ blockName)(parameterTypes);

    // As a method parameter

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    16/30

    16 of 30

    Mutating block variables

    Since variables within a block are just snapshots of what they were outside of the block scope, you must preceed any variablesthat you want to mutate within the block with __block , such as:

    Retain cycles

    Since blocks strongly capture all variables within the scope of the block, you have to be careful how you setup your blocks code.Here are two examples of retain cycles:

    In both of these cases, the object which performs the block owns the block, which also owns the object. This creates a loop, or aretain cycle, which means the memory is eventually leaked.

    To get around this warning you can either refactor the code to be:

    Or you can use a __weak object:

    Back to top

    Control Statements

    Objective-C uses all of the same control statements that other languages have:

    If-Else If-Else

    -- ( v o i dvo id ) someMethodTha tTakesABlock :someMethodTha tTakesABlock : (returnType (^ ^ )(parameterTypes)) blockName {

    // Block code here

    };

    // As an argument to a method call

    [someObject someMethodThatTakesABlock: : ^ ^ returnType (parameters) {

    // Block code here

    }];

    // As a typedef

    t y p e d e ft y p e d e f r e t u r n Ty p ere tu rnType (^ ^TypeName)(parameterTypes);

    TypeName blockName = = ^̂ (parameters) { // Block code here

    };

    __block i n ti n t someIncrementer = = 0 ;

    [someObject someMethodThatTakesABlock:^ :^ {

    someIncrementer++ + + ;

    }];

    [someObject someMethodThatTakesABlock:^ :^ {

    [someObject performSomeAction]; // Will raise a warning

    }];

    [self someMethodThatTakesABlock:^ : ^ {

    [self performSomeAction]; // Will raise a warning

    }];

    [self someMethodThatTakesABlock:^ : ^ {

    [object performSomeAction]; // No retain cycle here

    }];

    __weak typeof(self) weakSelf = = self;

    [self someMethodThatTakesABlock:^ : ^ {

    [weakSelf performSomeAction]; // No retain cycle here

    }];

    i fif (someTestCondition) { // Code to execute if the condition is true

    } elsee l s e i f if (someOtherTestCondition) {

    // Code to execute if the other test condition is true

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    17/30

    17 of 30

    Ternary Operators

    The shorthand notation for an if-else statement is a ternary operator of the form: someTestCondition ? doIfTrue : doIfFalse;

    Example:

    There is also another lesser known form: A ?: B; which basically returns A if A is YES or non-nil, otherwise it returns B.

    For Loops

    Fast Enumeration

    where arrayOfPeople can be any object that conforms to the NSFastEnumeration protocol. NSArray and NSSet enumerate over theirobjects, NSDictionary enumerates over keys, and NSManagedObjectModel enumerates over entities.

    While Loop

    Do While Loop

    Switch

    Switch statements are often used in place of if statements if there is a need to test if a certain variable matches the value of another constant or variable. For example, you may want to test if an error code integer you received matches an existingconstant value or if it's a new error code.

    } elsee l s e {

    // Code to execute if the prior conditions are false

    }

    -- (NSString * * ) s t r ingForTrueOrFa l se :s t r ingForTrueOrFa l se : ( BOOLBOOL) trueOrFalse{

    re tu rnret urn trueOrFalse ? ? @"True" :: @"False" ;

    }

    fo rf o r ( i n tin t i = = 0 ; i < < totalCount; i++ ++) {

    // Code to execute while i < totalCount

    }

    fo rfor (Person * *person in in arrayOfPeople) {

    // Code to execute each time

    }

    w h i l ewh il e (someTextCondition) {

    // Code to execute while the condition is true

    }

    dodo {

    // Code to execute while the condition is true

    } whi l ewh il e (someTestCondition);

    swi tchswitch (errorStatusCode)

    {

    caseca se kRPServerErrorCode:

    // Code to execute if it matches

    b r e a kb r e a k ;

    caseca se kRPNetworkErrorCode:

    caseca se kRPWifiErrorCode:

    caseca se kRPSystemErrorCode:

    // Code to execute if it matches

    b r e a kb r e a k ;

    de fau l t :d e f a u l t :

    // Code to execute if nothing else matched b r e a kb r e a k ;

    }

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    18/30

    18 of 30

    Note: switch statements are fallthrough: when control reaches the matched case (or default block if nothing matches), itcontinues execution of the next statements in the source code (including default ) until the break statement or the end of switchis reached. This also allows multiple values to match the same point without any special syntax; they are just listed with empty bodies.

    Exiting Loops

    return : Stops execution and returns to the calling function. It can also be used to return a value from a method.

    break : Used to stop execution of a loop.

    Newer enumeration methods now have special BOOL variables (e.g. BOOL *stop ) that are used to stop loop execution. Setting thatvariable to YES within the loop is similar to calling break .

    Back to top

    Enumeration

    Fast enumeration was already mentioned in the control statements section, but many collection classes also have their ownblock-based methods for enumerating over a collection.

    Block-based methods perform almost as well as using fast enumeration, but they just provide extra options for enumeratingover collections. An example of block-based enumeration over an NSArray would be:

    Back to top

    Extending Classes

    There are a few different ways to extend a class in Objective-C, with some approaches being much easier than others.

    Approach Difficulty Purpose

    Inheritance Easy Used if all you want to do is inherit behavior from another class, such as NSObject

    Category Easy Used if all you need to do is add additional methods to that class. If you also need to add instancevariables to an existing class using a category, you can fake this by using associative references.

    Delegation Easy Used to allow one class to react to changes in or influence behavior of another class whileminimizing coupling.

    Subclass Can bedifficult

    Used if you need to add methods and properties to an existing class or if you want to inheritbehavior from an existing class. Some classes are not designed to be subclassed.

    Swizzle Can be

    difficult

    Swizzling allows you to replace a method in an existing class with one of your own making. This

    approach can lead to a lot of unexpected behavior, so it should be used very sparingly.

    Inheritance

    Inheritance essentially allows you to create concrete subclasses, which typically have specialized behavior, while inheriting allmethods and properties from a superclass which are specified as @public or @protected within the superclass' header file.

    Looking through any framework or open source project, you can see the use of inheritance to not only get behavior for free, butto also consolidate code and allow it to be easily reused. Examples of this approach can be seen with any of the mutableframework classes such as NSMutableString which is a subclass of NSString .

    In Objective-C, all objects have much of their behavior defined by the NSObject class through the act of class inheritance.Without inheritance, you would have to implement common methods like object or class equality checks on your own and you'dend up with a lot of duplicate code across classes.

    NSArray * * people = = @[ @"Bob" , @"Joe" , @"Penelope" , @"Jane" ];

    [people enumerateObjectsUsingBlock:^ :^ (NSString * * nameOfPerson, NSUInteger idx, B O O LBOOL ** stop) {

    NSLog( @"Person's name is: %@" , nameOfPerson);

    }];

    // MyClass inherits all behavior from the NSObject class

    @in te r face@ i n t e r f a c e M y C l a s sM y C l a s s : NSObjec tN S O b j e c t

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    19/30

    19 of 30

    Inheritance inherently creates coupling between classes, so be sure to take this into consideration.

    Categories

    Categories are a very useful and easy way of extending classes, especially when you don't have access to the original source code(such as for Cocoa Touch frameworks and classes). A category can be declared for any class and any methods that you declare ina category will be available to all instances of the original class, as well as any subclasses of the original class . At runtime,there's no difference between a method added by a category and one that is implemented by the original class.

    Categories are also useful to:

    Declare informal protocols

    Group related methods similar to having multiple classes

    Break up a large class implementation into multiple categories, which helps with incremental compilation

    Easily configure a class differently for different applications

    Implementation

    Categories are named with the format: ClassYouAreExtending +DescriptorForWhatYouAreAdding

    As an example, let's say that we need to add a new method to the UIImage class (and all subclasses) that allows us to easily resizeor crop instances of that class. You'd then need to create a header/implementation file pair named UIImage+ResizeCrop with thefollowing implementation:

    UIImage+ResizeCrop.h

    UIImage+ResizeCrop.m

    You could then call these methods on any instances of UIImage or it's subclasses such as:

    Associative References

    Unless you have access to the source code for a class at compile time, it is not possible to add instance variables and properties toa class by using a category. Instead, you have to essentially fake this by using a feature of the Objective-C runtime called

    associative references .For example, let's say that we want to add a public property to the UIScrollView class to store a reference to a UIView object, butwe don't have access to UIScrollView 's source code. We would have to create a category on UIScrollView and then create a pair of

    // Class implementation

    @end@end

    @in te r face@ i n t e r f a c e U I I m a g eU I I m a g e (Res izeCrop)(Res izeCrop)

    -- (UIImage * * ) c r o p p e d I m a g e Wi t h S i z e :c roppedImageWi thS ize : (CGSize) size ;

    -- (UIImage * * ) r e s i z e d I m a g e Wi t h S i z e :re s i zedImageWi thS ize : (CGSize) size ;

    @end@end

    #impor t "UI Image+Res izeCrop .h" # impor t "UI Image+Res izeCrop .h"

    @ i m p l e m e n t a t i o n@ i m p l e m e n t a t i o n U I I m a g eU I I m a g e ( R e s i z e C r o p )(Res izeCrop)

    -- (UIImage * * ) c r o p p e d I m a g e Wi t h S i z e :c roppedImageWi thS ize : (CGSize) size

    {

    // Implementation code here

    }

    -- (UIImage * * ) r e s i z e d I m a g e Wi t h S i z e :re s i zedImageWi thS ize : (CGSize) size

    {

    // Implementation code here

    }

    UIImage * *croppedImage = = [userPhoto croppedImageWithSize: :photoSize];

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    20/30

    20 of 30

    getter/setter methods for this new property to store a reference like this:

    UIScrollView+UIViewAdditions.h

    UIScrollView+UIViewAdditions.m

    Let's explain a bit about what's happening here:

    We create a static key called UIScrollViewMyCustomView that we can use to get and set the associated object. Declaring it asstatic ensures that it is unique since it always points to the same memory address.

    Next, we declare the property we are adding as @dynamic which tells the compiler that the getter/setter is not implementedby the UIScrollView class itself.

    Within the setter, we use willChangeValueForKey followed by didChangeValueForKey to ensure that we notify any key-valueobservers of a change to this property.

    Within the setter, we use objc_setAssociatedObject to store a reference to the object that we really care about, customViewunder the static key that we created. & is used to denote that it is a pointer to a pointer to UIScrollViewMyCustomView

    Within the getter, we retrieve the object reference using objc_getAssociatedObject and a pointer to the static key

    We could then use the property just like we would any other property:

    More info from the docs:

    The [objc_setAssociatedObject] function takes four parameters: the source object, a key, the value, and an association policyconstant. The key is a void pointer.

    The key for each association must be unique. A typical pattern is to use a static variable. The policy specifies whether theassociated object is assigned, retained, or copied, and whether the association is be made atomically or non-atomically. Thispattern is similar to that of the attributes of a declared property

    The possible property declaration attributes are:

    OBJC_ASSOCIATION_RETAIN_NONATOMIC, OBJC_ASSOCIATION_ASSIGN, OBJC_ASSOCIATION_COPY_NONATOMIC,

    # impor t # impor t

    @in te r face@ i n t e r f a c e UIScro l lViewU I S c r o l l Vi e w ( U I Vi e w A d d i t i o n s )( U I Vi e w A d d i t i o n s )

    @ p r o p e r t y@property (nonatomic, strong) UIView * *myCustomView;

    @end@end

    #impor t "UIScro l lView+UIViewAddi t ions .h" # impor t "UIScro l lView+UIViewAddi t ions .h"

    # impor t # impor t

    s t a t i cs t a t i c cha rc h a r UIScrollViewMyCustomView;

    @ i m p l e m e n t a t i o n@ i m p l e m e n t a t i o n UIScro l lViewUIScro l lView (UIViewAddi t ions )( U I Vi e w A d d i t i o n s )

    @dynamic@dy nam ic myCustomView;

    -- ( v o i dvo id ) se tMyCus tomView:se tMyCus tomView: (UIView * * ) customView

    { [self willChangeValueForKey: : @"myCustomView" ];

    objc_setAssociatedObject(self, & & UIScrollViewMyCustomView, customView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

    [self didChangeValueForKey: : @"myCustomView" ];

    }

    -- (UIView * * ) myCus tomViewmyCus tomView {

    re tu rnre tu rn objc_getAssociatedObject(self, & &UIScrollViewMyCustomView);

    }

    @end@end

    UIScrollView * *scrollView = = [[UIScrollView alloc] init];

    scrollView.myCustomView = = [[UIView alloc] init];

    NSLog( @"Custom view is %@" , scrollView.myCustomView);

    // Custom view is

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    21/30

    21 of 30

    OBJC_ASSOCIATION_RETAIN, OBJC_ASSOCIATION_COPY

    Class Extension Categories

    In the section about declaring classes, it shows how the private instance variables and properties within a class are actually added to the class by using an anonymous (unnamed) category, also known as a class extension.

    Class extensions are the only way that you can add variables and properties using a category, so you must have access to thesource code at compile time in order to use this method.

    Core Data Categories

    Categories are very useful when you are working with Core Data models and want to add additional methods to anNSManagedObject subclass without worrying about Xcode writing over the model class each time you migrate a model.

    Model classes should be kept to a minimum, containing only the model properties and Core Data generated accessor methods.All others, such as transient methods, should be implemented in a category on the model class.

    Naming Conflicts

    Great advice from Apple's docs(https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html)

    :

    Because the methods declared in a category are added to an existing class, you need to be very careful about method names.

    If the name of a method declared in a category is the same as a method in the original class, or a method in another categoryon the same class (or even a superclass), the behavior is undefined as to which method implementation is used at runtime.This is less likely to be an issue if you’re using categories with your own classes, but can cause problems when usingcategories to add methods to standard Cocoa or Cocoa Touch classes.

    Delegation

    Delegation is basically a way to allow one class to react to changes made in another class or to influence the behavior of anotherclass while minimizing coupling between the two.

    The most commonly known example of the delegate pattern in iOS is with UITableViewDelegate and UITableViewDataSource .When you tell the compiler that your class conforms to these protocols, you are essentially agreeing to implement certainmethods within your class that are required for a UITableView to properly function.

    Conforming to an Existing Protocol

    To conform to an existing protocol, import the header file that contains the protocol declaration (not necessary for framework classes). Then, insert the protocol name within < > symbols and separate multiple protocols by a comma. Both options shownbelow will work just fine, but I prefer to keep them in the header file since it feels cleaner to me.

    Option 1 : In your .h file:

    Option 2 : In the .m file:

    // Class extensions for private variables / properties

    @in te r face@ i n t e r f a c e M y C l a s sM y C l a s s ()

    {

    in ti n t somePrivateInt;

    // Re-declare as a private read-write version of the public read-only property

    @proper ty@p ro pe rt y (readwrite, nonatomic, strong) SomeClass * *someProperty;

    }

    @end@end

    #impor t "RPLoca t ionManager.h" # impor t "RPLoca t ionManager.h"

    @in te r face@ i n t e r f a c e MyViewCont ro l l e rM y Vi e w C o n t r o l l e r : UIViewCont ro l l e rUIViewCont ro l l e r >

    @end@end

    #impor t "MyViewCont ro l l e r.h" # impor t "MyViewCont ro l l e r.h"

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    22/30

    22 of 30

    Creating Your Own Protocol

    To create your own protocol for other classes to conform to, follow this syntax:

    RPLocationManager.h

    When we declare the @protocol named RPLocationManagerDelegate , all methods are defaulted to being @required so it's notnecessary to explicitly state this. However, if you want certain methods to be @optional for conforming classes to implement, youmust state this.

    Additionally, it is necessary to weakly declare an anonymously typed property called delegate which also references theRPLocationManagerDelegate protocol.

    Sending Delegate Messages

    In the example above, RPLocationManager.h declares some methods that the class which is acting as the delegate mustimplement. Within RPLocationManager.m itself, you could implement these a few different ways, but we'll just show two cases: a)required methods; b) optional methods.

    Required Methods

    Optional Methods

    @inte r face@ i n t e r f a c e MyViewCont ro l l e rM y Vi e w C o n t r o l l e r () < >

    {

    // Class extension implementation

    }

    @end@end

    #impor t # impor t

    // Declare your protocol and decide which methods are required/optional

    // for the delegate class to implement

    @ p r o t o c o l@ p r o t o c o l R P L o c a t i o n M a n a g e r D e l e g a t eRPLoca t ionManagerDe lega te

    -- ( v o i dvo id )didAcquireLocation: : (CLLocation * *)location;

    -- ( v o i dvo id ) d idFa i lToAcqu i reLoca t ionWi thEr ro r :d idFa i lToAcqu i reLoca t ionWi thEr ro r : (NSError * * ) error ;

    @ o p t i o n a l@ o p t i o n a l

    -- ( v o i dvo id )didFindLocationName: : (NSString * * )locationName;

    @end@end

    @in te r face@ i n t e r f a c e RPLoca t ionManagerR P L o c a t i o n M a n a g e r : NSObjec tN S O b j e c t

    // Create a weak, anonymous object to store a reference to the delegate class

    @ p r o p e r t y@pr ope rty (nonatomic, weak) idi d >delegate;

    // Implement any other methods here

    @end@end

    -- ( v o i dvo id ) upda teLoca t ionupda teLoca t ion

    {

    // Perform some work

    // When ready, notify the delegate method

    [self.delegate didAcquireLocation: :locationObject];

    }

    -- ( v o i dvo id ) reve r seGeoCoderever seGeoCode

    {

    // Perform some work

    // When ready, notify the delegate method

    i fif ([self.delegate respondsToSelector: : @ s e l e c t o r@selector(didFindLocationName: :)]) {

    [self.delegate didFindLocationName: : locationName]; }

    }

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    23/30

    23 of 30

    The only difference between @required and @optional methods is that you should always check if the referenced delegateimplemented an optional method before calling it on that class.

    Implementing Delegate Methods

    To implement a delegate method, just conform to the protocol like was discussed earlier, and then write it as if it was a normalmethod:

    MyViewController.m

    Subclassing

    Subclassing is essentially the same as inheritance, but you would typically create the subclass to either

    Override a method or property implementation in the superclass; or

    Create specialized behavior for the subclass (e.g. Toyota is a subclass of Car ... it still has tires, an engine, etc, but it hasadditional custom behavior that uniquely makes it a Toyota )

    Many design patterns, such as categories and delegation, exist so that you don't have to subclass another class. For example, theUITableViewDelegate protocol was created to allow you to provide the implementation of methods liketableView:didSelectRowAtIndexPath: in your own class instead of having to subclass UITableView to override that method.

    Other times, classes like NSManagedObject are designed to be easily subclassed. The general rule of thumb is to subclass anotherclass only if you can satisfy the Liskov substitution principle (http://en.wikipedia.org/wiki/Liskov_substitution_principle) :

    If S is a subtype of T, then objects of type T in a program may be replaced with objects of type S without altering any of thedesirable properties of that program.

    Example

    Let's assume that we want to model cars. All cars have similar behavior and characteristics, so let's put some of that in asuperclass called Car .

    Car.h

    Car.m

    -- ( v o i dvo id ) d idF indLoca t ionName:d idF indLoca t ionName: (NSString * * ) locationName

    {

    NSLog( @"We found a location with the name %@" , locationName);

    }

    # impor t # impor t

    @in te r face@ i n t e r f a c e Ca rC ar : NSObjec tNSObjec t

    @ p r o p e r t y@property (nonatomic, strong) NSString * *make;

    @ p r o p e r t y@property (nonatomic, strong) NSString * *model;

    @ p r o p e r t y@p ro pe rt y (nonatomic, assign) NSInteger year;

    -- ( v o i dvo id ) s t a r t E n g i n es t a r t E n g i n e ;

    -- ( v o i dvo id ) p r e s s G a s P e d a lp r e s s G a s P e d a l ;

    -- ( v o i dvo id ) p r e s s B r a k e P e d a lp r e s s B r a k e P e d a l ;

    @end@end

    #impor t "Car.h" # impor t "Car.h"

    @ i m p l e m e n t a t i o n@ i m p l e m e n t a t i o n C arCa r

    -- ( v o i dvo id ) s t a r t E n g i n es t a r t E n g i n e

    {

    NSLog( @"Starting the engine." );

    }

    -- ( v o i dvo id ) p r e s s G a s P e d a lp r e s s G a s P e d a l

    {

    NSLog( @"Accelerating..." );

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    24/30

    24 of 30

    Now when we want to spawn off new car makes and models with unique characteristics, we use the Car superclass as a startingpoint and then add custom behavior in the subclass.

    Toyota.h

    Toyota.m

    Even though pressBrakePedal is declared in the Car class, that method is still accessible in the Toyota class due to inheritance.

    Designated Initializers

    Often times, classes implement designated class initializers to allow for easy instantiation. If you override the main designatedinitializer for a class or provide a new designated initializer, it's important to ensure that you also override all other designatedinitializers so they use your new implementation instead of the superclass version. If you forget to do so and someone calls oneof the secondary designated initializers on your subclass, they will get behavior from the superclass instead.

    }

    -- ( v o i dvo id ) p r e s s B r a k e P e d a lp r e s s B r a k e P e d a l

    {

    NSLog( @"Decelerating..." );

    }

    @end@end

    #impor t "Car.h" # impor t "Car.h"

    @in te r face@ i n t e r f a c e Toyo taTo y o t a : C arCa r

    -- ( v o i dvo id ) p r e v e n t A c c i d e n tp r e v e n t A c c i d e n t ;

    @end@end

    #impor t "Toyo ta .h" # impor t "Toyo ta .h"

    @ i m p l e m e n t a t i o n@ i m p l e m e n t a t i o n Toyo taToyo ta

    -- ( v o i dvo id ) s t a r t E n g i n es t a r t E n g i n e

    {

    // Perform custom start sequence, different from the superclass

    NSLog( @"Starting the engine." );

    }

    -- ( v o i dvo id ) p r e v e n t A c c i d e n tp r e v e n t A c c i d e n t

    {

    [self pressBrakePedal];

    [self deployAirbags];

    }

    -- ( v o i dvo id ) d e p l o y A i r b a g sd e p l o y A i r b a g s

    {

    NSLog( @"Deploying the airbags." );

    }

    @end@end

    // The new designated initializer for this class

    -- (instancetype) i n i t Wi t h F u l l N a m e :i n i t Wi t h F u l l N a m e : (NSString * * ) fullName

    {

    i fif (self = = [super init]) {

    _fullName = = fullName;

    [self commonSetup];

    } r e tu rnretu rn self;

    }

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    25/30

    25 of 30

    If you'd rather someone not use a default initializer for some rare case, you should throw an exception and provide them with analternative solution:

    Overriding Methods

    If you're subclassing another class to override a method within that class, you must be a little cautious. If you want to maintainthe same behavior as the superclass, but just modify it slightly, you can call super within the override like this:

    If you don't want any of the superclass's behavior for the overridden method, simply leave out that call to super , but be carefulthat there aren't any memory or object lifecycle consequences for doing so.

    Additionally, if the superclass has primitive methods upon which other derived methods are implemented, you must ensure thatyou override all necessary primitive methods necessary for the derived methods to work properly.

    Caveats

    Certain classes don't lend themselves well to being easily subclassed and therefore subclassing is discouraged in those cases. Anexample of this is when trying to subclass a class cluster such as NSString or NSNumber . Class clusters have quite a few privateclasses within them so it's difficult to ensure that you have overridden all of the primitive methods and designated initializerswithin the class cluster properly.

    Swizzling

    As is often the case, clarity is better than cleverness. As a general rule, it's typically better to work around a bug in a methodimplementation than it is to replace the method by using method swizzling. The reason being that other people using your codemight not realize that you replaced the method implementation and then they are stuck wondering why a method isn'tresponding with the default behavior.

    For this reason, we don't discuss swizzling here but you are welcome to read up on it here (http://www.mikeash.com/pyblog/friday-qa-2010-01-29-method-replacement-for-fun-and-profit.html) .

    Back to top

    Error Handling

    Errors are typically handled three different ways: assertions, exceptions, and recoverable errors. In the case of assertions andexceptions, they should only be used in rare cases since crashing your app is obviously not a great user experience.

    Assertions

    Assertions are used when you want to ensure that a value is what it is supposed to be. If it's not the correct value, you force exitthe app.

    // Provide a sensible default for other initializers

    -- (instancetype) i n i tin i t

    {

    r e tu rnre tu rn [self initWithFullName: : @"Default User" ];

    }

    -- (instancetype) i n i tin i t {

    [NSException raise: :NSInvalidArgumentException f o r m a t :f o r m a t : @"%s Using the %@ initializer directly is not supported. Use %@ instead." , __PRETTY_FUNCTIO

    N__, NSStringFromSelector(@selector@se lec tor (init)), NSStringFromSelector(@se lec tor @selector(initWithFrame: :))];

    r e tu rnr e t u r n nil ;

    }

    -- ( v o i dvo id ) myMethodmyMethod

    {

    [super myMethod];

    // Provide your additional custom behavior here

    }

    NSAssert(someCondition, @"The condition was false, so we are exiting the app." );

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    26/30

    26 of 30

    Important: Do not call functions with side effects in the condition parameter of this macro. The condition parameter is notevaluated when assertions are disabled, so if you call functions with side effects, those functions may never get called when you build the project in a non-debug configuration.

    Exceptions

    Exceptions are only used for programming or unexpected runtime errors. Examples: attempting to access the 6th element of anarray with 5 elements (out-of-bounds access), attempting to mutate immutable objects, or sending an invalid message to anobject. You usually take care of these sorts of errors with exceptions when an application is being created rather than at runtime.

    An example of this might be if you have a library which requires an API key to use.

    Try-Catch

    If you're worried that a block of code is going to throw an exception, you can wrap it in a try-catch block but keep in mind thatthis has slight performance implications

    Recoverable Errors

    Many times, methods will return an NSError object in a failure block or as a pointer to a pointer (in the case of NSFileManager ).These are typically returned for recoverable errors and offer a much more pleasant user experience since they can clue the userinto what just went wrong.

    Creating Your Own Errors

    It's also possible to create your own NSError objects to return in methods.

    // Check for an empty API key

    -- ( v o i dvo id ) checkForAPIKeycheckForAPIKey

    {

    i fi f ( ! ! self.apiKey || | | ! !self.apiKey.length) {

    [NSException raise: : @"Forecastr" format: : @"Your Forecast.io API key must be populated before you can access

    the API." , nil ];

    }

    }

    @try@ t r y {

    // The code to try here

    }

    @ca tch@ca tch (NSException * * exception) {

    // Handle the caught exception

    }

    @f ina l ly@ f i n a l l y {

    // Execute code here that would run after both the @try and @catch blocks

    }

    [forecastr getForecastForLocation: : location success:^ : ^ ( i di d JSON) {

    NSLog( @"JSON response was: %@" , JSON);

    } failure:^ :^ (NSError * *error, i di d response) {

    NSLog( @"Error while retrieving forecast: %@" , error.localizedDescription);

    }];

    // Error domain & enums

    NSString * * c o n s tconst kFCErrorDomain = = @"com.forecastr.errors" ;

    t y p e d e ft y p e d e f N S _ E N U MN S _ E N U M(NSInteger, ForecastErrorType) {

    kFCCachedItemNotFound,

    kFCCacheNotEnabled

    };

    @ i m p l e m e n t a t i o n@ i m p l e m e n t a t i o n F o r e c a s t rF o r e c a s t r

    -- ( v o i dvo id ) checkForecas tCacheForURLSt r ing :checkForecas tCacheForURLSt r ing : (NSString * * ) urlString

    s u c c e s s :success : ( v o i dvo id (^ ^ )( i did cachedForecast)) success f a i l u r e :f a i lu re : ( v o i dvo id (^ ^)(NSError * *error)) failure

    {

    // Check cache for a forecast

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    27/30

    27 of 30

    Back to top

    Passing Information

    We have already discussed many ways of passing information between classes, such as through methods or delegates, but we'lldiscuss a few more here and also give one more example of delegation.

    Passing through Delegate

    A very common way to pass data from one view controller to another is to use a delegate method. An example of this would be if you had a modal view with a table that showed over top of your view controller and you needed to know which table cell the userpressed.

    AddPersonViewController.h (the modal view)

    AddPersonViewController.m

    GroupViewController.m (the normal view)

    We left out a few implementation details, such as conforming to the AddPersonTableViewControllerDelegate , but you are welcometo read the delegation section for those.

    i di d cachedItem = = [forecastCache objectForKey: :urlString];

    i fif (cachedItem) {

    success(cachedItem);

    } e l see l s e {

    // Return an error since it wasn't found

    failure([NSError errorWithDomain: : kFCErrorDomain code: : kFCCachedItemNotFound userInfo: : nil ]);

    }

    }

    @end@end

    #impor t # impor t

    # impor t "Pe r son .h" # impor t "Pe r son .h"

    @ p r o t o c o l@ p r o t o c o l AddPersonTab leViewCont ro l l e rDe lega teAddPersonTab leViewCont ro l l e rDe lega te

    -- ( v o i dvo id )didSelectPerson: :(Person * *)person;

    @end@end

    @in te r face@ i n t e r f a c e AddPersonTab leViewCont ro l l e rAddPersonTab leViewCont ro l l e r : UITab leViewCont ro l l e rUITab leViewCont ro l l e r

    @ p r o p e r t y@pr ope rty (nonatomic, weak) idi d >delegate;

    @end@end

    // Other implementation details left out

    -- ( v o i dvo id ) t ab leView:tab leView: (UITableView * * ) tableView d idSe lec tRowAtIndexPa th :d idSe lec tRowAtIndexPa th : (NSIndexPath * * ) indexPath

    {

    Person * * person = = [people objectAtIndex: : indexPath.row];

    [self.delegate didSelectPerson: :person];

    }

    // Other implementation details left out, such as showing the modal view

    // and setting the delegate to self

    #p ragma mark - AddPersonTab leViewCont ro l l e rDe lega te #pragma mark - AddPersonTab leViewCont ro l l e rDe lega te

    -- ( v o i dvo id ) d idSe lec tPe r son :d idSe lec tPe r son : (Person * * ) person

    {

    [self dismissViewControllerAnimated: : YES completion: : nil ];

    NSLog( @"Selected person: %@" , person.fullName);

    }

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    28/30

    28 of 30

    Also, notice that we dismiss the modal view controller ( AddPersonViewController ) in the same class that originally showed it.This is the recommended approach by Apple.

    NSNotificationCenter

    Notifications are broadcast messages that are used to decouple classes and establish anonymous communication betweenobjects at runtime. Notifications may be posted by any number of objects and received by any number of objects thus enablingone-to-many and many-to-many relationships between objects.

    Note : Notifications are sent synchronously so if your observer method takes a long time to return, you are essentially prevently

    the notification from being sent to other observing objects.

    Registering Observers

    You can register to be notified when a certain event has happened, including system notifications, such as a UITextField whichhas begun editing.

    When the UITextFieldTextDidBeginEditingNotification notification is broadcast by the OS framework, thetextFieldDidBeginEditing: will be called by NSNotificationCenter and an object will be sent along with the notification thatcould contain data.

    A possible implementation of the textFieldDidBeginEditing: method could be:

    Removing Observers

    It's important to remove yourself as an observer when the class is deallocated, otherwise NSNotificationCenter will attempt tocall a method on a deallocated class and a crash will ensue.

    Posting Notifications

    You can also create and post your own notifications. It's best practice to keep notification names in a constants file so that youdon't accidentally misspell one of the notification names and sit there trying to figure out why the notification wasn'tsent/received.

    Naming notifications:

    Notifications are identified by NSString objects whose names are composed in this way:

    [Name of associated class] + [Did | Will] + [UniquePartOfName] + Notification

    Declare a string constant, using the notification name as the string's value:

    Post notification:

    [[NSNotificationCenter defaultCenter] addObserver: :self selector: : @ s e l e c t o r@selector(textFieldDidBeginEditing: : )

    n a m e :n a m e : UITextFieldTextDidBeginEditingNotification object: :self];

    #pragma mark - Tex t F ie ld Obse rve r s #pragma mark - Tex t F ie ld Obse rve r s

    -- ( v o i dvo id ) t e x t F i e l d D i d B e g i n E d i t i n g :t ex tF ie ldDidBeg inEdi t ing : (NSNotification * * ) notification

    {

    // Optional check to make sure the method was called from the notification

    i fif ([notification.name isEqualToString: : UITextFieldTextDidBeginEditingNotification])

    {

    // Do something

    }

    }

    -- ( v o i dvo id ) d e a l l o cd e a l l o c

    {

    [[NSNotificationCenter defaultCenter] removeObserver: :self];

    }

    // Remember to put the extern of this in the header file

    NSString * * c o n s tconst kRPAppDidResumeFromBackgroundNotification = = @"RPAppDidResumeFromBackgroundNotification" ;

    [[NSNotificationCenter defaultCenter] postNotificationName: : kRPAppDidResumeFromBackgroundNotification object: :self];

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    29/30

    29 of 30

    View Controller Properties

    When you are preparing to display a new view controller, you can assign data to one of it's properties prior to display:

    Storyboard Segue

    When you are transitioning from one view controller to another in a storyboard, there is an easy way to pass data between thetwo by implementing the prepareForSegue:sender: method:

    User Defaults

    User defaults are basically a way of storing simple preference values which can be saved and restored across app launches. It isnot meant to be used as a data storage layer, like Core Data or sqlite.

    Storing Values

    Always remember to call synchronize on the defaults instance to ensure they are saved properly.

    Retrieving Values

    There are also other convenience methods on NSUserDefaults instances such as boolForKey: , stringForKey: , etc.

    Back to top

    Common Patterns

    Singletons

    Singleton's are a special kind of class where only one instance of the class exists for the current process. They are a convenientway to share data between different parts of an app without creating global variables or having to pass the data around manually,but they should be used sparingly since they often create tighter coupling between classes.

    To turn a class into a singleton, you place the following method into the implementation ( .m ) file, where the method name isprefixed with shared plus another word which best describes your class. For example, if the class is a network or locationmanager, you would name the method sharedManager instead of sharedInstance .

    MyViewController * *myVC == [[MyViewController alloc] init];

    myVC.someProperty = = self.someProperty;

    [self presentViewController: :myVC animated: : YES completion: : nil ];

    # p r a g m a m a r k - S e g u e H a n d l e r #pragma mark - Segue Hand le r

    -- ( v o i dvo id ) p repa reForSegue :p repa reForSegue : (UIStoryboardSegue * * ) segue s e n d e r :s e n d e r : ( i di d ) sender

    {

    i fif ([segue.identifier isEqualToString: : @"showLocationSearch" ] {

    [segue.destinationViewController setDelegate: :self];

    } e l see l s e i f if ([segue.identifier isEqualToString: : @"showDetailView" ]) {

    DetailViewController * * detailView = = segue.destinationViewController;

    detailView.location = = self.location;

    }

    }

    NSUserDefaults * *userDefaults = = [NSUserDefaults standardUserDefaults];

    [userDefaults setValue: : @"Some value" forKey: : @"RPSomeUserPreference" ];[userDefaults synchronize];

    NSUserDefaults * *userDefaults = = [NSUserDefaults standardUserDefaults];

    idid someValue = = [userDefaults valueForKey: : @"RPSomeUserPreference" ];

    ++ (instancetype) sha redIns tancesha redIns tance

    {

    s t a t i cs t a t i c idi d sharedInstance = = nil ;

  • 8/18/2019 Gitprint Iwasrobbed Objective C CheatSheet Blob Master README.md

    30/30

    The use of dispatch_once ensures that this method is only ever executed once, even if it's called multiple times across many classes or different threads.

    If the above code were placed within MyClass , then you would get a reference to that singleton class in another class with thefollowing code:

    Back to top

    s t a t i cs t a t i c d i spa tch_once_ td i s p a t c h _ o n c e _ t onceToken;

    dispatch_once(& & onceToken, ̂ ^ {

    sharedInstance = = [[self alloc] init];

    });

    r e tu rnreturn sharedInstance;

    }

    MyClass * * myClass = = [MyClass sharedInstance];

    [myClass doSomething];

    NSLog( @"Property value is %@" , myClass.someProperty);