Cocoa Fundamentals Guide

 

Chain of message disptach table

Every Objective-C object hides a data structure whose first member - or instance variable - is the isa pointer.

The isa pointer, as the name suggests, points to the object's class, which is an object in its own right and is compiled from the class definition. The class object maintains a dispatch table consisting essentially of pointers to the methods it implements; It also holds a pointer to its superclass, which has its own dispatch table and superclass pointer. Through this chain of references, an object has access to the method implementations of its class and all its superclass. The isa pointer is critical to the message-dispatch mechanism and to the dynamism of Cocoa objects.

The Dynamism of Objective-C

  • Dynamic typing : determining the class of an object at runtime
  • Dynamic binding: determining the method to invoke at runtime
  • Dynamic loading: adding new modules to a program at runtime

Runtime factors determine which receiver is chosen and which method is invoked.

The runtime’s message-dispatch machinery enables dynamic binding. When you send a message to a dynamically typed object, the runtime system uses the receiver’s isa pointer to locate the object’s class, and from there the method implementation to invoke. The method is dynamically bound to the message. And you don’t have to do anything special in your Objective-C code to reap the benefits of dynamic binding. It happens routinely and transparently every time you send a message, especially one to a dynamically typed object.

Dynamic loading, the final type of dynamism, is a feature of Cocoa that depends on Objective-C for runtime support. With dynamic loading, a Cocoa program can load executable code and resources as they’re needed instead of having to load all program components at launch time. 

 

Category:

Syntactically, the only difference is the name of the category, which follows the @interface or@implementation directive and is put in parentheses.

Protocol:

A class adopts a protocol by specifying the protocol, enclosed by angle brackets, at the end of its @interface directive, just after the superclass. 

  1. You can check whether a class conforms to a particular protocol by sending it a conformsToProtocol: message.
  2. Before invoking optional methods, it should verify that they’re implemented using the respondsToSelector: method.

In a declaration of a type—a method, instance variable, or function—you can specify protocol conformance as part of the type. You thus get another level of type checking by the compiler, one that’s more abstract because it’s not tied to particular implementations. 

- (void)draggingEnded:(id <NSDraggingInfo>)sender;

 Here the object referred to in the parameter can be of any class type, but it must conform to the NSDraggingInfo protocol.

 Using objective-c

NSEnumerator *enm = [sorted_args objectEnumerator];

The message expression is on the right side of the assignment, enclosed by the square brackets.

NSClassName *variable = [receiver message];

However, this diagram is simplistic and not really accurate. A message consists of a selector name and the parameters of the message. The Objective-C runtime uses a selector name, such as objectEnumerator above, to look up a selector in a table in order to find the method to invoke. A selector is a unique identifier that represents a method and that has a special type, SEL. Because it’s so closely related, the selector name used to look up a selector is frequently called a selector as well. The above statement thus is more correctly shown as:

NSClassName *variable = [receiver selector];
NSClassName *variable = [receiver keyword1:param1 keyword2:param2];

 

 Important Objective-C defined types and literals

id: The dynamic object type. its negative literal is nil.

Class: The dynamic class type. Its negative literal is Nil.

SEL: The data type (typedef) of a selector. The negative literal of this type is NULL.

BOOL: A Boolean type. The literal values are YES and NO.

 

Object Creation

The creation of a cocoa object always takes place in two stages: allocation and initialization. Without both steps an object generally isn't usable. Although in almost all cases initialization immediately follows allocation, the two operations play distinct roles in the formation of an object.

To allocate an object, you send the message alloc or allocWithZone: to the object's class. In return, you get a "raw" (uninitialized) instance of the class. The alloc variant of the method uses the applicaiton's default zone. A zone is a page-aligned area of memory for holding related objects and data allocated by an application.

An allocation message does other important things besides allocating memory:

  • It sets the object’s retain count to one.

  • It initializes the object’s isa instance variable to point to the object’s class, a runtime object in its own right that is compiled from the class definition.

  • It initializes all other instance variables to zero (or to the equivalent type for zero, such as nilNULL, and 0.0).

An object’s isa instance variable is inherited from NSObject, so it is common to all Cocoa objects. After allocation sets isa to the object’s class, the object is integrated into the runtime’s view of the inheritance hierarchy and the current network of objects (class and instance) that constitute a program. Consequently an object can find whatever information it needs at runtime, such as another object’s place in the inheritance hierarchy, the protocols that other objects conform to, and the location of the method implementations it can perform in response to messages.

 

posted on 2012-06-21 09:11  grep  阅读(310)  评论(0编辑  收藏  举报