
The syntax may appear alien because it uses a messaging structure rather than function calling
With messaging, the lookup is always at runtime and uses dynamic binding
The memory for objects are always allocated in heap space and never on the stack
Creating another variable pointing to the same location does not create a copy but rather yields two variables pointing to the same object
Pointers are allocated on the stack
When non-object types (int, float, double, char, etc.) are the only data to be held, a structure, such as CGRect, is usually used
Objective-C is a superset of C, adding object-oriented features
If you only need to know that a class exists rather than the full details, use @class to forward declare the class rather than import the class's header file. Then important the header file in the implementation file so you know how to use it
You must import the header that defines the superclass from which you are inheriting
If you declare any protocols that your class conforms to, they have to be fully defined and not forward declared
The complier needs to be able to see the methods the protocol defines rather than simply that a protocol does exist from a forward declaration
If you are creating an array using the literal syntax, if any of the objects is nil, an exception is thrown
If you want to make a mutable variant of a literal syntax variable, you must make a mutableCopy of the variable
There is always a better to define a constant than using a preprocessor define
The usual convention for constants is to prefix with the letter k for constants that are local to a translation unit
A constant that does not need to be exposed to the outside world should be defined in the implementation file where it is used
Static means the variable is local to the translation unit in which it is defined
A translation unit is the input the compiler receives to geenerate one object file. In the case of Objective-C, this is usually the implementation file
For global constants, declare them in the header file with extern <type> *const variableName; and define them in the implementation file with <type> *const variableName = value;
For external constants, prefix the name with the name of the class that the constant relates to to help avoid potential clashes
Avoid preprocessor defines. They don't contain any type information and are simply a find and replace executed before compilation
Use enumerations to give readable names to values used for the states of a state machine, options passed to methods, and error status codes
An enumeration is nothing more than a way of naming constant values
Add a typedef to the enumeration definition so the type can be used instead of the full enum
When used for switching on an enumeration that defines a state machine, it is best not to have a default entry. This helps if you add to the enumeration, because the compiler will warn that the switch does not handle all the values
You will usually want to use nonatomic properties on iOS
Direct access to instance variables is faster, as it does not have to go through Objective-C method dispatch
Always use direct access to instance variables within an initializer method
The == operator compares the pointers themselves rather than the objects to which they point
Use the isEqual: instead
Rather than checking equality of class objects, use isKindOfClass:
Class clusters have init methods to return an object of various subclasses based on the type passed into the init method and then overriding methods in the subclasses
There should be just one designated initializer that all other initializers call
You should always override the designated initializer of your superclass if you have a designated initializer with a different name
Implement the description method to be able to log the object with NSLog(@"%@")
Create objects that are immutable
Provide methods to mutate collections held by objects rather than exposing a mutable collection as a property
If a method returns a newly created value, the first word in the method name should be its type
A parameter should be immediately preceded by a noun describing its type
Avoid abbreviations and instead use full names
Methods that return a Boolean should be prefixed by either has or is
Avoid abbreviations of types in method names
Prefix private method names, i.e. _ or p_
Private methods only need to be declared in the implementation file
NSError objects contain an error domain, an error code, and user info
Implement copyWithZone:zone to implement the NSCopying protocol for your own classes
The contents of a shallow copy point to the same objects as the original. The contents of a deep copy point to copies of the original contents
Objective-C does not have multiple inheritance, so protocols provide a way to define a set of methods that a class should implement
Protocols are a good way of documenting an interface to your code
Categories provide you with a way to add methods to a class without having to subclass it
Use delegate and data source protocols for interobject communication
The Delegate pattern defines an interface that any object can conform to in order to become the delegate of another object. This other object talks back to its delegate to get some information or to inform the delegate when interesting things happen
A delegate property will usually be defined using a weak attribute
Implementing the delegate is a matter of declaring that your class implements the delegate protocol and then implementing any methods you want from the protocol
You can declare that a class implements a protocol in either the interface or the class continuation category
Before any optional method is called on the delegate, introspection should be used to determine whether the delegate responds to that selector
Use categories to split a class implementation into more manageable fragments
Use the class-continuation category to hide private instance variables and methods
Automatic Reference Counting adds in the retains and releases for you
You should never call dealloc
You should only us dealloc to release references to other objects and to unregister anything that needs to be, such as Key-Value Observing (KVO) or NSNotificationCenter notifications
If you don't own an object, you should not retain it and instead use __weak
Sending a message to a deallocated object is completely unsafe
Blocks can use anything from the scope in which they are defined
block type syntax: return_type (^block_name)(parameters) = ^{...}
Use the dispatch queue to ensure synchronization
Use [object performSelector:@selector(selectorName)] to dynamically call a method at runtime. This can cause a memory leak. Can also use it with up to two parameters with withObject:. Can combine with afterDelay:.
dispatch_async(dispatch_get_main_queue(), ^{ [self doSomething]; });
Use dispatch_once for thread-safe single-time code execution
enumerateObjectsUsingBlock and enumerateKeysAndObjectsUsingBlock to enumerate over objects
