Chapter 3. Objective-C Primer

The Objective-C language is a superset of ANSI C with special syntax and runtime extensions that make object-oriented programming possible. Objective-C syntax is uncomplicated, but powerful in its simplicity. You can mix standard C with Objective-C code. Programmers familiar with C and object-oriented programming techniques often find themselves right at home with Objective-C in a matter of days.

This chapter is divided into two main sections. The first section is a basic language summary listing all additions to the language. The second section summarizes some of the most frequently used aspects of the language.

See Inside Cocoa: Object-Oriented Programming and the Objective-C Language in /Developer/Documentation/Cocoa for complete details.

Language Summary

Objective-C adds a small number of constructs to the C language and defines a handful of conventions used to effectively interact with the runtime system.

Messages

Message expressions are enclosed in square brackets:

[receiver message]

The receiver can be:

  • A variable or expression that evaluates to an object (including the variable self)

  • A class name (indicating the class object)

  • super (indicating an alternative search for the method implementation)

The message is the name of a method plus any arguments passed to it.

Defined Types

The principal types used in Objective-C are defined in the header file objc/objc.h:

TypeDefinition
id

An object (a pointer to its data structure)

Class

A class object (a pointer to the class data structure)

SEL

A selector, a compiler-assigned code that identifies a method name

IMP

A pointer to a method implementation that returns an id

BOOL

A Boolean value, either YES or NO

id can be used to type any kind of object, class, or instance. In addition, class names can be used as type names to statically type instances of a class. A statically typed instance is declared to be a pointer to an instance of its class or to an instance of any class it inherits from.

The objc.h header file also defines these useful terms:

TypeDefinition
nil

A null object pointer, (id)0

Nil

A null class pointer, (Class)0

Preprocessor Directives

The preprocessor understands these new notations:

NotationDefinition
#import

Imports a header file. This directive is identical to #include, except that it won’t include the same file more than once.

//

Begins a comment that continues to the end of the line.

Compiler Directives

Directives to the compiler begin with @. The following directives are used to declare and define classes, categories, and protocols:

DirectiveDefinition
@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

@end

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

The following mutually exclusive directives specify the visibility of instance variables:

DirectiveDefinition
@private

Limits the scope of an instance variable to the class that declares it

@protected

Limits the instance variable scope to declaring and inheriting classes

@public

Removes restrictions on the scope of instance variables

The default is @protected.

In addition, there are directives for these particular purposes:

DirectiveDefinition
@class

Declares the names of classes defined elsewhere.

@selector(method)

Returns the compiled selector that identifies method.

@protocol(name)

Returns the name protocol (an instance of the Protocol class). (@protocol is also valid without (name) for forward declarations.)

@encode(spec)

Yields a character string that encodes the type structure of spec.

@defs(classname)

Yields the internal data structure of classname instances.

Classes

A new class is declared with the @interface directive. The interface file for its superclass must be imported:

#import "ItsSuperclass.h"

@interface ClassName : ItsSuperclass < protocol list >
{
    instance variable declarations
} 
method declarations 
@end

Everything but the compiler directives and class name is optional. If the colon and superclass name are omitted, the class is declared to be a new root class. If any protocols are listed, the header files where they’re declared must also be imported.

A file containing a class definition imports its own interface:

#import "ClassName.h"

@implementation ClassName
method definitions 
@end

Categories

You can add methods to a class by declaring them in an interface file under a category name and defining them in an implementation file under the same name. The category name indicates that the methods are additions to a class declared elsewhere, not a new class.

A category can be an alternative to a subclass. Rather than define a subclass to extend an existing class, through a category you can add methods to the class directly. For example, you could add categories to NSArray and other Cocoa classes. As in the case of a subclass, you don’t need source code for the class you’re extending.

The methods the category adds become part of the class type. For example, methods added to the NSArray class in a category will be among the methods the compiler will expect an NSArray instance to have in its repertoire. Methods added to the NSArray class in a subclass would not be included in the NSArray type. (This matters only for statically typed objects, since static typing is the only way the compiler can know an object’s class.)

Category methods can do anything that methods defined in the class proper can do. At runtime, there’s no difference. The methods the category adds to the class are inherited by all the class’s subclasses, just like other methods.

A category is declared in much the same way as a class. The interface file that declares the class must be imported:

#import "ClassName.h"

@interface ClassName ( CategoryName ) < protocol list >
method declarations 
@end

The protocol list and method declarations are optional. If any protocols are listed, the header files where they’re declared must also be imported.

Like a class definition, a file containing a category definition imports its own interface:

#import "CategoryName.h"

@implementation ClassName ( CategoryName )
method definitions
@end

Protocols

Class and category interfaces declare methods that are associated with a particular class—mainly methods that the class implements. Informal and formal protocols, on the other hand, declare methods not associated with a class, but which any class, and perhaps many classes, might implement.

A protocol is simply a list of method declarations, unattached to a class definition. For example, these methods that report user actions on the mouse could be gathered into a protocol:

-(void)mouseDown:(NSEvent *)theEvent;
-(void)mouseDragged:(NSEvent *)theEvent;
-(void)mouseUp:(NSEvent *)theEvent;

Any class that wanted to respond to mouse events could adopt the protocol and implement its methods.

Protocols free method declarations from dependency on the class hierarchy, so they can be used in ways that classes and categories cannot. Protocols list methods that are (or may be) implemented somewhere, but the identity of the class that implements them is not of interest. What is of interest is whether or not a particular class conforms to the protocol—whether it has implementations of the methods the protocol declares. Thus objects can be grouped into types not just on the basis of similarities due to the fact that they inherit from the same class but also on the basis of their similarity in conforming to the same protocol. Classes in unrelated branches of the inheritance hierarchy might be typed alike because they conform to the same protocol.

Protocols can play a significant role in object-oriented design, especially when a project is divided among many implementors or incorporates objects developed in other projects. Cocoa software uses them heavily to support interprocess communication through Objective-C messages.

However, an Objective-C program doesn’t need to use protocols. Unlike class definitions and message expressions, they’re optional. Some Cocoa frameworks use them; some don’t. It all depends on the task at hand.

Formal protocols are declared using the @protocol directive:

@protocol ProtocolName
< protocol list >
method declarations
@end

The list of incorporated protocols and the method declarations are optional. The protocol must import the header files that declare any protocols it incorporates.

Within source code, protocols are referred to using the similar @protocol() directive, where the parentheses enclose the protocol name.

Protocol names listed within angle brackets <...> are used to do three different things:

  • In a protocol declaration, to incorporate other protocols (as shown before)

  • In a class or category declaration, to formally adopt the protocol (as shown under Section 3.1.5 and Section 3.1.6)

  • In a type specification, to limit the type to objects that conform to the protocol

Within protocol declarations, these type qualifiers support remote messaging:

Type QualifierDefinition
oneway

The method is for asynchronous messages and has no valid return value.

in

The argument passes information to the remote receiver.

out

The argument gets information returned by reference.

inout

The argument both passes information and gets information.

bycopy

A copy of the object, not a proxy, should be passed or returned.

byref

A reference to the object, not a copy, should be passed or returned.

Method Declarations

The following conventions are used in method declarations:

  • A + precedes declarations of class methods.

  • A - precedes declarations of instance methods.

  • Arguments are declared after colons (:). Typically, a label describing the argument precedes the colon. Both labels and colons are considered part of the method name.

  • Argument and return types are declared using the C syntax for typecasting.

  • The default return and argument type for methods is id, not int as it is for functions. (However, the modifier unsigned when used without a following type always means unsigned int.)

Method Implementations

Each method implementation is passed two hidden arguments:

  • The receiving object (self)

  • The selector for the method (_cmd)

Within the implementation, both self and super refer to the receiving object. super replaces self as the receiver of a message to indicate that only methods inherited by the implementation should be performed in response to the message.

Methods with no other valid return typically return void.

Naming Conventions

The names of files that contain Objective-C source code have a .m extension. Files that declare class and category interfaces or that declare protocols have the .h extension typical of header files.

Class, category, and protocol names generally begin with an uppercase letter; the names of methods and instance variables typically begin with a lowercase letter. The names of variables that hold instances usually also begin with lowercase letters.

In Objective-C, identical names that serve different purposes don’t clash. Within a class, names can assigned freely:

  • A class can declare methods with the same names as methods in other classes.

  • A class can declare instance variables with the same names as variables in other classes.

  • An instance method can have the same name as a class method.

  • A method can have the same name as an instance variable.

Likewise, protocols and categories of the same class have protected namespaces:

  • A protocol can have the same name as a class, a category, or anything else.

  • A category of one class can have the same name as a category of another class.

However, class names are in the same namespace as global variables and defined types. A program can’t have a global variable with the same name as a class.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.205.214