Part 3: Objective-C newbie summary guide

Part 3: Objective-C newbie summary guide

Objective-C is the object-oriented language used for MacOS X and iOS app programming. Here’s the thing: Apple’s documentation is fine in esence but it is an utter mess in organization. So my job here is to read several boring “Introductory guides” (how many different “introductory” chapters can there be?) and all the subindexes and mash them up into one, trying my best to sort out the fuss.*


*This is no master guide, just my own annotations while starting to learn the language.

References:

[qd_list]

[/qd_list]

Index

  1. Objective C is a superset of C
  2. The Runtime System
  3. Classes: interface & implementation
    1. Interface
    2. Implementation
    3. Class names
    4. Abstract classes
    5. Root class – NSObject and isa variable
  4. Objects
    1. id and nil
    2. Mutability
    3. Memory management
  5. Variables: Static & dynamic typing
    1. Naming variables and properties
    2. The scope of instance variables
    3. Static and dynamic typing
  6. Methods and messaging
    1. Instance method: –
    2. Class method: +
    3. Messaging
    4. Accessor methods (getters and setters)
    5. Dot notation
    6. Naming methods
    7. Polymorphism
  7. Declared properties
    1. Attributes
    2. Synthesizing
    3. @dynamic
    4. Subclassing with properties
  8. Delegation
    1. Delegation and the Cocoa frameworks
    2. Notifications
    3. Data source
  9. Strings (NSString): @
  10. Blocks
  11. Protocols
    1. Declaring a formal protocol
    2. Adopting a protocol
    3. Conforming to a protocol
  12. Categories
  13. Associative References
  14. Define types and coding strategies

↑TOP

Objective-C is a Superset of the C Language

Objective-C extends the standard ANSI C language. Its additions to C are mostly based on Smalltalk, one of the first object-oriented programming languages. It provides object-orientated programming capabilities, such as:

  • – Definition of new classes
  • – Class and instance methods
  • – Method invocation (called messaging)
  • – Declaration of properties (and automatic synthesizing of accessor methods from them)
  • – Static and dynamic typing (dynamic runtime)
  • – Blocks—encapsulated segments of code that can be executed at any time
  • – Extensions to the base language such as protocols and categories
  • – Language-level support for object graph management
  • – Object literals

.h – Header files. Header files contain class, type, function, and constant declarations.
.m – Implementation files. A file with this extension can contain both Objective-C and C code. It is sometimes called a source file.
.mm – Implementation files. An implementation file with this extension can contain C++ code in addition to Objective-C and C code. Use this extension only if you actually refer to C++ classes or features from your Objective-C code.

NOTE: an #import directive is like C’s #include directive, except that it makes sure that the same file is never included more than once.

When building apps for OS X or iOS, you’ll spend most of your time working with objects. Those objects are instances of Objective-C classes, some of which are provided for you by Cocoa or Cocoa Touch frameworks and some of which you’ll write yourself.

↑TOP

The Runtime System

The Objective-C language defers as many decisions as it can from compile time and link time to runtime. Whenever possible, it dynamically performs operations such as creating objects and determining what method to invoke. Therefore, the language requires not just a compiler, but also a runtime system to execute the compiled code. The runtime system acts as a kind of operating system for the Objective-C language; it’s what makes the language work. Typically, however, you don’t need to interact with the runtime directly.

↑TOP

Classes: Interface (declaration) & Implementation

As in most other object-oriented languages, classes in Objective-C provide the basic construct for encapsulating data with related behaviour. An object is a runtime instance of a class. For OS X or iOS development, you don’t need to create objects from scratch to solve every conceivable problem; instead you have a large library of existing objects available for your use, provided by Cocoa (for OS X) and Cocoa Touch (for iOS). In Objective-C, the interface and implementation are usually placed in separate files so that you only need to make the interface public.

Interface

(usually an .h file)
The interface portion contains the class declaration and defines the instance variables and methods associated with the class. In other words, it defines the public interface between instances of the class and the outside world.

MyClass syntax for declaring a class called MyClass, which inherits from Cocoa’s root class NSObject

@interface ClassName : ItsSuperclass
	{
	// Instance variable declarations.
	}
	// Method and property declarations.
@end

If you want public variables to be part of the class (a.k.a. instance variables, ivars or member variables) then you declare them inside the braces ({and}), otherwise they are declared as a global variable which has nothing to do with the class.

@interface XYZPerson : NSObject
	{
	int myinstancevariable;
	}

	@property NSString *firstName;
	@property NSString *lastName;
	@property NSNumber *yearOfBirth;
	- (void)sayHello;  // a method declaration

	@end

	int myglobalvariable;
	...

	XYZPerson* a = [[XYZPerson alloc] init];
	NSLog(@"%d", [a myinstancevariable]);
	NSLog(@"%d", myglobalvariable );

The interface file must be included in any source module that depends on the class interface—that includes any module that creates an instance of the class, sends a message to invoke a method declared for the class, or mentions an instance variable declared in the class. This directive is identical to #include, except that it makes sure that the same file is never included more than once.

#import "Rectangle.h"

Implementation

(usually a .m file)
The implementation portion contains the actual code for the methods of the class. An implementation should always import its interface file as one of the first lines of code.

#import "XYZPerson.h"

@implementation XYZPerson
	- (void)sayHello {
    	NSLog(@"Hello, World!");  // code goes here
	}
@end

Inheritance

When one class inherits from another, the child inherits all the behavior and properties defined by the parent. It also has the opportunity either to define its own additional behavior and properties, or override the behavior of the parent.

Creating a new method with the same name as an ancestor’s method will override it with new instructions. Because an object has memory allocated for every instance variable it inherits, you can’t override an inherited variable by declaring a new one with the same name. If you try, the compiler will complain.

NSMutableString class inheritance Inheritance of NSObject

Root class – NSObject and isa variable

Objective-C defines a root class from which the vast majority of other classes inherit, called NSObject (has no superclass). When one object encounters another object, it expects to be able to interact using at least the basic behavior defined by the NSObject class description. Although it is not mandatory, inheriting this ability from the NSObject class is much simpler and much more reliable than reinventing it in a new class definition.

When a class object creates a new instance, the new object contains not only the instance variables and methods that were defined for its class but also those defined for its superclass and for its superclass’s superclass, all the way back to the root class. Thus, the isa instance variable defined in the NSObject class becomes part of every object. It connects each object to its class.

Objective-C

UIButton class inheritance

Class Names Must be unique

It’s important to note that the name of each class must be unique within an app, even across included libraries or frameworks. If you attempt to create a new class with the same name as an existing class in a project, you’ll receive a compiler error. A good trick is to define classes you create with a two or three letter prefix. This is the historical reason behind the classes that start with NS or UI (like NSString), looking back at the time when Cocoa was used to build apps for the NeXTStep Operating System. And oh! Remember C (and thus Objective-C) is case sensitive!!

Abstract classes

Some classes are designed only or primarily so that other classes can inherit from them. These abstract classes group methods and instance variables that can be used by a number of subclasses into a common definition.

The NSObject class is the canonical example of an abstract class in Cocoa. You never use instances of the NSObject class in an application—it wouldn’t be good for anything; it would be a generic object with the ability to do nothing in particular.

↑TOP

Objects

An instance of a class is an object (created by factory methods that belong to factory class objects). In essence, an object bundles a data structure (instance variables) and a group of operations (methods) into a self-contained programming unit.

In Objective-C, an object’s instance variables are internal to the object; generally, you get access to an object’s state only through the object’s methods.

To create a class instance you call the factory method:

id  myRectangle;
myRectangle = [Rectangle alloc];

This creates a new Rectangle object dynamically allocating memory for it and initializing almost everything to 0. For an object to be useful, it generally needs to be more completely initialized. That’s the function of an init method. If a class makes use of static or global variables, the initialize method is a good place to set their initial values.

Initialization typically follows immediately after allocation:

myRectangle = [[Rectangle alloc] init];

id and nil

Object identifiers are of a distinct data type: id. This type is the general type for any kind of object regardless of class and can be used for instances of a class and for class objects themselves. The keyword nil is defined as a null object, an id with a value of 0.

Mutability: Whether a Represented Value Can Be Changed

Immutable objects: The internal contents must be set when an object is created, and cannot subsequently be changed by other objects. Example: All NSString and NSNumber objects are immutable. If you need to represent different content, you must use a new instance.

Mutable objects: The internal contents can be changed at runtime, for example by appending characters as they are received over a network connection. Example: An instance of the NSMutableString class.

Memory Management

In any program, it is important to ensure that objects are deallocated when they are no longer needed—otherwise your application’s memory footprint becomes larger than necessary. It is also important to ensure that you do not deallocate objects while they’re still being used.

Objective-C offers three mechanisms for memory management that allow you to meet these goals:

– Automatic Reference Counting (ARC), where the compiler reasons about the lifetimes of objects.
– Manual Reference Counting (MRC, sometimes referred to as MRR for “manual retain/release”), where you are ultimately responsible for determining the lifetime of objects.
– Garbage collection, where you pass responsibility for determining the lifetime of objects to an automatic “collector.”

↑TOP

Variables: Static and dynamic typing.

Naming variables and properties

By contrast with classes, variable and property names need only be unique within the class in which they are defined.

The Scope of Instance Variables

To enforce the ability of an object to hide its data, the compiler limits the scope of instance variables—that is, limits their visibility within the program. But to provide flexibility, it also lets you explicitly set the scope at four levels. Each level is marked by a compiler directive:

[ws_table id=”2″]

Scope of instance variables

Scope of instance variables

A scoping directive applies to all the instance variables listed after it, up to the next directive or the end of the list. In the following example, the age and evaluation instance variables are private; name, job, and wage are protected; and boss is public. By default, all unmarked instance variables are @protected.

@interface Worker : NSObject
	{
	char *name;
	@private
	int age;
	char *evaluation;
	@protected
	id job;
	float wage;
	@public
	id boss;
	}

Static (strong) and dynamic (weak) typing

Objective-C supports dynamic typing (a.k.a weak typing) for variables containing objects (ie. id), but it also supports static typing (a.k.a strong typing).

Statically typed variables –> include the class name in the variable type declaration giving the compiler information about the kind of object it is. Must always have asterisks (*) to indicate that they are C pointers.
Dynamically typed variables –> use the type id for the object instead. id already implies a pointer.

You find dynamically typed variables used in certain situations. For example, a collection object such as an array (where the exact types of the contained objects may be unknown) might use dynamically typed variables. Such variables provide tremendous flexibility and allow for greater dynamism in Objective-C programs.

This example shows statically and dynamically typed variable declarations:

MyClass *myObject1;  // Static typing
id       myObject2;  // Dynamic typing
NSString *userName;  // From Your First iOS App (static typing)

Static typing permits the compiler to do some type checking—for example, to warn if an object could receive a message that it appears not to be able to respond to—and to loosen some restrictions that apply to objects generically typed id. In addition, it can make your intentions clearer to others who read your source code. However, it doesn’t defeat dynamic binding or alter the dynamic determination of a receiver’s class at runtime.

An object can be statically typed to its own class or to any class that it inherits from.

↑TOP

Methods and messaging: Instance, Class & Accessors methods

Objective-C methods are conceptually similar to standard functions in C and other programming languages, though the syntax is quite different. Method return and parameter types are declared using the standard C syntax for casting one type to another. If a return or parameter type isn’t explicitly declared, it’s assumed to be the default type for methods and messages—an id.

A C function declaration looks like this:

void SomeFunction(SomeType value);

The equivalent Objective-C method declaration looks like this:

- (void)someMethod:(SomeType)value;
Declaration of a method named <code>insertObject:atIndex:</code>

Instance method: –

Is a method whose execution is scoped to a particular instance of the class. In other words, before you call an instance method, you must first create an instance of the class. Instance methods are the most common type of method.

Class method: +

Is a method whose execution is scoped to the method’s class, i.e. send messages to the class itself, not an object. It does not require an instance of an object to be the receiver of a message. You typically use class methods as factory methods to create new instances of the class or for accessing some piece of shared information associated with the class.

Messaging

When you want to call a method, you do so by messaging an object like:

[receiver message];

receiver –> object
message –> name of a method (selector) and any parameters that are passed to it.

For example, to send the insertObject:atIndex: message to an object held by the myArray variable, you would use the following syntax:

[myArray insertObject:anObject atIndex:0];

or to tell the myRectangle object to set its origin to the coordinates (30.0, 50.0):

[myRectangle setOriginX: 30.0 y: 50.0];

Accessor methods (getters and setters)

Accesor methods are instance methods that get (getter, in Cocoa’s terminology) or set (setter, in Cocoa’s terminology) the value of a property of an object, and thus are key to encapsulation.

getter: Returns the value of a property.

- (type) Name;
- (BOOL)isName;

setter: Sets the value of a property.

- (void)setName:(type)newName;
- (void)setName:(BOOL)newName;

Note the one exception is a property that is a Boolean value.

Dot-notation

Objective-C provides a dot-notation syntax for invoking accessor methods. Dot syntax uses the same pattern that accessing C structure elements uses

The following two syntaxis are the same:
equivalent syntaxis, getters and setters


[myInstance setValue:10];

and

printf("myInstance value: %d", [myInstance value]);

// Each member of the path is an object.
x = person.address.street.name;
x = [[[person address] street] name];
// An example of using a setter.
person.address.street.name = @"Oxford Road";
[[[person address] street] setName: @"Oxford Road"];

Naming methods

By contrast with classes, method names need only be unique within the class in which they are defined.

Polymorphism

In particular, an object can be operated on by only those methods that were defined for it. Therefore, two objects can respond differently to the same message if both of them implement the same method their own way.

↑TOP

Declared properties

Declared properties are a language-level convenience that allow the runtime to synthesize accessor methods for a class. Although using accessor methods has significant advantages, writing accessor methods is a tedious process. In other words, they eliminate the need to implement a getter and setter method (accessor methods) for each property exposed in the class and the compiler will create — or synthesize — actual getter and setter methods based on that declaration. Property attributes indicate data accessibility and storage considerations, such as readonly, copy or weak

declared properties

You include property declarations with the method declarations in your class interface.

A property in the general sense is some data encapsulated or stored by an object.
Property declarations take the form:

@property (attributes) Type propertyName;

The following lines of code illustrate a few examples of property declarations:

@property (copy) MyModelObject *theObject;  // Copy the object during assignment.
@property (readonly) NSView *rootView;      // Declare only a getter method.
@property (weak) id delegate;               // Declare delegate as a weak reference
@property BOOL flag;

Attributes

Some possible attributes are:

[ws_table id=”3″]

synthesizing

The compiler automatically synthesizes declared properties, but you can also use the @synthesize compiler directive to ask the compiler to generate the methods:

@synthesize flag, delegate, nameObject, rootView;

In synthesizing a property, it creates accessor methods for it as well as a private instance variable that “backs” the property.

Incidentally, when you declare a property you can specify custom names for the accessor methods, typically to make the getter methods of Boolean properties follow a conventional form, as shown here:

@property (assign, getter=isEnabled) BOOL enabled; // Assign new value, change name of getter method

@dynamic

You use the dynamic directive to tell the compiler that you will fulfill the API contract implied by a property either by providing method implementations directly or at runtime using other mechanisms such as dynamic loading of code or dynamic method resolution. It suppresses the warnings that the compiler would otherwise generate if it can’t find suitable implementations

Subclassing with properties

You can redeclare a property in a subclass, but (with the exception of readonly versus readwrite) you must repeat its attributes in whole in the subclasses. The same holds true for a property declared in a category or protocol — while the property may be redeclared in a category or protocol, the property’s attributes must be repeated in whole. You can override a readonly property to make it writable.

↑TOP

Delegation

Delegation is a simple and powerful pattern in which one object in a program acts on behalf of, or in coordination with, another object. The delegating object keeps a reference to the other object—the delegate—and at the appropriate time sends a message to it. The message informs the delegate of an event that the delegating object is about to handle or has just handled. The delegate may respond to the message by updating the appearance or state of itself or other objects in the application, and in some cases it can return a value that affects how an impending event is handled. The main value of delegation is that it allows you to easily customize the behavior of several objects in one central object.

Delegation and the Cocoa Frameworks

The delegating object is typically a framework object, and the delegate is typically a custom controller object. In a managed memory environment, the delegating object maintains a weak reference to its delegate; in a garbage-collected environment, the receiver maintains a strong reference to its delegate. Examples of delegation abound in the Foundation, UIKit, AppKit, and other Cocoa and Cocoa Touch frameworks.

An example of a delegating object is an instance of the NSWindow class of the AppKit framework. NSWindow declares a protocol, among whose methods is windowShouldClose:. When a user clicks the close box in a window, the window object sends windowShouldClose: to its delegate to ask it to confirm the closure of the window. The delegate returns a Boolean value, thereby controlling the behavior of the window object.

delegation in Objective-C

Notifications

The delegate of most Cocoa framework classes is automatically registered as an observer of notifications posted by the delegating object. The delegate need only implement a notification method declared by the framework class to receive a particular notification message. Following the example above, a window object posts an NSWindowWillCloseNotification to observers but sends a windowShouldClose: message to its delegate.

Data Source

A data source is almost identical to a delegate. The difference is in the relationship with the delegating object. Instead of being delegated control of the user interface, a data source is delegated control of data. The delegating object, typically a view object such as a table view, holds a reference to its data source and occasionally asks it for the data it should display. A data source, like a delegate, must adopt a protocol and implement at minimum the required methods of that protocol. Data sources are responsible for managing the memory of the model objects they give to the delegating view.

↑TOP

Strings

(NSString)
As a superset of C, Objective-C supports the same conventions for specifying strings as C. In other words, single characters are enclosed by single quotes and strings of characters are surrounded by double quotes. However, this could not be so simple, so Objective-C frameworks typically do not use C-style strings. Instead, they pass strings around as NSString objects.

This object comes with:
– built-in memory management for storing arbitrary-length strings,
– support for Unicode,
– printf-style formatting utilities,
– …

To access the shorthand for creating NSString objects from constant values, simply use @ object literal:

NSString *myString = @"My String\n";
NSString *anotherString = [NSString stringWithFormat:@"%d %@", 1, @"String"];

// Create an Objective-C string from a C string
NSString *fromCString = [NSString stringWithCString:"A C string" encoding:NSASCIIStringEncoding];

↑TOP

Blocks: ^

Blocks are objects that encapsulate segments of code to be executed at any time.

blocks

You can then call the block variable as if it were a function:

int result = myBlock(4); // result is 28

↑TOP

Protocols: < … >

Protocols simply define an interface that other classes are responsible for implementing. When your class implements the methods of a protocol, your class is said to conform to that protocol.

They are useful in at least three situations:
– To declare methods that others are expected to implement
– To declare the interface to an object while concealing its class
– To capture similarities among classes that are not hierarchically related

Declaring a Formal Protocol

The declaration of a protocol looks similar to that of a class interface, with the exceptions that protocols do not have a parent class and they do not define instance variables. The following example shows a simple protocol declaration with one method:

@protocol MyProtocol
    - (void)myProtocolMethod;
@end

Adopting a protocol

You specify in the interface block that your class conforms to, or adopts, a protocol by putting the name of the protocol in angle brackets () after the name of the class from which it inherits. Adopting a protocol is similar in some ways to declaring a superclass.

@interface HelloWorldViewController : UIViewController  {
}
@end

A class can adopt more than one protocol; names in the protocol list are separated by commas.

@interface Formatter : NSObject < Formatting, Prettifying >

Conforming to a Protocol

It’s possible to check whether an object conforms to a protocol by sending it a conformsToProtocol: message.

if ( ! [receiver conformsToProtocol:@protocol(MyXMLSupport)]  ) {
	// Object does not conform to MyXMLSupport protocol
}

You do not have to declare the protocol methods you implement because the protocol declaration already does that.

↑TOP

Categories: ( … )

A category is a feature of the Objective-C language that enables you to extend the interface of a class without having to subclass it, by adding methods to the class — even to one for which you do not have the source.

@interface ClassName (CategoryName)
   // method declarations
@end

You can also define an informal protocol by grouping the methods in a category.

↑TOP

Associative References

Associative references, available starting in OS X v10.6, simulate the addition of object instance variables to an existing class. Using associative references, you can add storage to an object without modifying the class declaration. This may be useful if you do not have access to the source code for the class, or if for binary-compatibility reasons you cannot alter the layout of the object.

 

Defined Types and Coding Strategies

Some reserved words that extend those in ANSI C are:

id – The dynamic object type. The negative literal for both dynamically and statically typed objects is nil.
Class – The dynamic class type. Its negative literal is Nil.
SEL – The data type (typedef) of a selector; this data type represents a method signature at runtime. Its negative literal is NULL.
BOOL – A Boolean type. The literal values are YES and NO.
self – a local variable that you can use within a message implementation to refer to the current object (equivalent to this in C++).
super – refering to the superclass.

Awesome CSS3 coded iPhone

Next Article

Awesome CSS3 coded iPhone

One Comment

Cancel

  1. Awesome