hn-classics/_stories/1994/11841657.md

922 lines
42 KiB
Markdown
Raw Normal View History

2018-02-23 18:19:40 +00:00
[Source](http://www.nextop.de/NeXTstep_3.3_Developer_Documentation/Foundation/Classes/NSObject.htmld/index.html "Permalink to NSObject")
# NSObject
Enterprise Objects Framework Release 1.0 Copyright ©1994 by NeXT Computer, Inc.  All Rights Reserved.
| ----- |
| | **NSObject** |
| ----- |
| | **Inherits From:** | none  _(NSObject is the root class)_ |
| ------ | ------------------ | ------------------------------------ |
| | **Conforms To:** | NSCoding
NSObject |
| | | |
| | **Declared In:** | foundation/NSObject.h |
| ----- |
| | **Class Description** |
| ----- |
| | NSObject is the root class of all ordinary Objective C inheritance hierarchies; it's the one class that has no superclass. From NSObject, other classes inherit a basic interface to the run-time system for the Objective C language.  It's through NSObject that instances of all classes obtain their ability to behave as objects.
Among other things, the NSObject class provides inheriting classes with a framework for creating, initializing, deallocating, copying, comparing, and archiving objects, for performing methods selected at run-time, for querying an object about its methods and its position in the inheritance hierarchy, and for forwarding messages to other objects. For example, to ask an object what class it belongs to, you'd send it a **class** message (**class** is declared in the NSObject protocol). To find out whether it implements a particular method, you'd send it a **respondsToSelector:** message.
The NSObject class is an abstract class; programs use instances of classes that inherit from NSObject, but never of NSObject itself.
**Initializing an Object to Its Class**
Every object is connected to the run-time system through its **isa** instance variable, inherited from the NSObject class. **isa** identifies the object's class; it points to a structure that's compiled from the class definition. Through **isa**, an object can find whatever information it needs at run time--such as its place in the inheritance hierarchy, the size and structure of its instance variables, and the location of the method implementations it can perform in response to messages.
Because all objects directly or indirectly inherit from the NSObject class, they all have this variable.  The defining characteristic of an "object" is that its first instance variable is an **isa** pointer to a class structure.
The installation of the class structure--the initialization of **isa**\--is one of the responsibilities of the **alloc**, **allocWithZone:**, and **new** methods, the same methods that create (allocate memory for) new instances of a class. In other words, class initialization is part of the process of creating an object; it's not left to the methods, such as **init**, that initialize individual objects with their particular characteristics.
**Instance and Class Methods**
Every object requires an interface to the run-time system, whether it's an instance object or a class object.  For example, it should be possible to ask either an instance or a class about its position in the inheritance hierarchy or whether it can respond to a particular message.
So that this won't mean implementing every NSObject method twice, once as an instance method and again as a class method, the run-time system treats methods defined in the root class in a special way: |
| ----- |
| | _Instance methods defined in the root class can be performed both by instances_
_and by class objects._ |
| ----- |
| | A class object has access to class methods--those defined in the class and those inherited from the classes above it in the inheritance hierarchy--but generally not to instance methods.  However, the run-time system gives all class objects access to the instance methods defined in the root class.  Any class object can perform any root instance method, provided it doesn't have a class method with the same name.
For example, a class object could be sent messages to perform NSObject's **respondsToSelector:** and **perform:withObject:** instance methods: |
![][1]SEL method = @selector(riskAll:);
![][1]if ( [MyClass respondsToSelector:method] )
![][1][MyClass perform:method withObject:self];
| ----- |
| | When a class object receives a message, the run-time system looks first at the receiver's repertoire of class methods. If it fails to find a class method that can respond to the message, it looks at the set of instance methods defined in the root class. If the root class has an instance method that can respond (as NSObject does for **respondsToSelector:** and **perform:withObject:**), the run-time system uses that implementation and the message succeeds.
Note that the only instance methods available to a class object are those defined in the root class. If MyClass in the example above had reimplemented either **respondsToSelector:** or **perform:withObject:**, those new versions of the methods would be available only to instances. The class object for MyClass could perform only the versions defined in the NSObject class. (Of course, if MyClass had implemented **respondsToSelector:** or **perform:withObject:** as class methods rather than instance methods, the class would perform those new versions.)
**Interface Conventions**
The NSObject class defines a number of methods that other classes are expected to override.  Often, NSObject's default implementation simply returns **self**.  Putting these "empty" methods in the NSObject class serves two purposes: |
| ----- |
| | ![][2] | It means that every object can readily respond to certain standard messages, such as **load** or **init**, even if the response is to do nothing. It's not necessary to check (using **respondsToSelector:**) before sending the message. |
| - | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| | ![][2] | It establishes conventions that, when followed by all classes, make object interactions more reliable.  These conventions are explained in full under the method descriptions. |
| ----- |
| | **Instance Variables** |
| ----- |
| | Class **isa**; |
| ----- |
| | isa | A pointer to the instance's class structure. |
| ----- |
| | **Adopted Protocols** |
| ----- |
| | NSCoding | ![][3] encodeWithCoder: |
| ----- |
| | ![][3] initWithCoder: |
| ----- |
| | NSObject | ![][3] autorelease |
| ----- |
| | ![][3] class
![][3] conformsToProtocol:
![][3] hash
![][3] isEqual:
![][3] isKindOfClass:
![][3] isMemberOfClass:
![][3] isProxy
![][3] perform:
![][3] perform:withObject:
![][3] perform:withObject:withObject:
![][3] release
![][3] respondsToSelector:
![][3] retain
![][3] retainCount
![][3] self
![][3] zone |
| ----- |
| | **Method Types** |
| ----- |
| | Initializing the class | \+ initialize |
| ----- |
| | Creating and destroying instances |
| ----- |
| | \+ allocWithZone: |
| ----- |
| | \+ alloc
![][3] init
\+ new
![][3] dealloc |
| ----- |
| | Identifying classes | \+ class |
| ----- |
| | \+ superclass |
| ----- |
| | Testing class functionality | \+ instancesRespondToSelector: |
| - | ---------------------------- | ------------------------------ |
| | Testing protocol conformance | \+ conformsToProtocol: |
| | | |
| | Obtaining method information | ![][3] methodForSelector: |
| ----- |
| | \+ instanceMethodForSelector:
![][3] methodSignatureForSelector: |
| ----- |
| | Describing objects | \+ description |
| ----- |
| | ![][3] description |
| ----- |
| | Posing | \+ poseAsClass: |
| | | |
| | Error handling | ![][3] doesNotRecognizeSelector: |
| | | |
| | Forwarding messages | ![][3] forwardInvocation: |
| | | |
| | Dynamic loading | \+ load |
| | | |
| | Archiving | ![][3] awakeAfterUsingCoder: |
| ----- |
| | ![][3] classForArchiver
![][3] classForCoder
![][3] replacementObjectForArchiver
![][3] replacementObjectForCoder:
\+ setVersion:
\+ version |
| ----- |
| | **Class Methods** |
| ----- |
| | **alloc** |
| ----- |
| | \+ **alloc** |
| ----- |
| | Returns a new instance of the receiving class. The **isa** instance variable of the new object is initialized to a data structure that describes the class; memory for all other instance variables is set to 0. This method invokes **allocWithZone:**, passing the default zone (as returned by **NSDefaultMallocZone()**) as its argument.
A version of the **init** method should be used to complete the initialization process.  For example: |
![][1]TheClass *newObject = [[TheClass alloc] init];
| ----- |
| | Other classes shouldn't override **alloc** to add code that initializes the new instance.  Instead, class-specific versions of the **init** method should be implemented for that purpose.  Versions of the **new** method can also be implemented to combine allocation and initialization.
**See also:**  \+ **allocWithZone:**, ![][3] **init**, + **new**
**allocWithZone:** |
| ----- |
| | \+ **allocWithZone:**(NSZone *)_zone_ |
| ----- |
| | Returns a new instance of the receiving class.  Memory for the new object is allocated from _zone_.
The **isa** instance variable of the new object is initialized to a data structure that describes the class; memory for its other instance variables is set to 0.  A version of the **init** method should be used to complete the initialization process. For example: |
![][1]TheClass *newObject = [[TheClass allocWithZone:someZone] init];
| ----- |
| | The **allocWithZone:** method shouldn't be overridden to include any initialization code.  Instead, class-specific versions of the **init** method should be implemented for that purpose.
When one object creates another, it's often a good idea to make sure they're both allocated from the same region of memory.  The **zone** method (declared in the NSObject protocol) can be used for this purpose; it returns the zone where the receiver is located.  For example: |
![][1]id myCompanion = [[TheClass allocWithZone:[self zone]] init];
| ----- |
| | **See also:**  \+ **alloc**, ![][3] **init**
**class** |
| ----- |
| | \+ (Class)**class** |
| ----- |
| | Returns **self**.  Since this is a class method, it returns the class object.
When a class is the receiver of a message, it can be referred to by name. In all other cases, the class object must be obtained through this, or a similar method. For example, here SomeClass is passed as an argument to the **isKindOfClass:** method (declared in the NSObject protocol): |
![][1]BOOL test = [self isKindOfClass:[SomeClass class]];
| ----- |
| | **See also:**  ![][3] **name**, ![][3] **class** (NSObject protocol)
**conformsToProtocol:** |
| ----- |
| | \+ (BOOL)**conformsToProtocol:**(Protocol *)_aProtocol_ |
| ----- |
| | Returns YES if the receiving class conforms to _aProtocol_, and NO if it doesn't.
A class is said to "conform to" a protocol if it adopts the protocol or inherits from another class that adopts it. Protocols are adopted by listing them within angle brackets after the interface declaration. Here, for example, MyClass adopts the imaginary AffiliationRequests and Normalization protocols: |
![][1]@interface MyClass : NSObject <AffiliationRequests, Normalization>
| ----- |
| | A class also conforms to any protocols that are incorporated in the protocols it adopts or inherits.  Protocols incorporate other protocols in the same way that classes adopt them.  For example, here the AffiliationRequests protocol incorporates the Joining protocol: |
![][1]@protocol AffiliationRequests <Joining>
| ----- |
| | When a class adopts a protocol, it must implement all the methods the protocol declares.  If it adopts a protocol that incorporates another protocol, it must also implement all the methods in the incorporated protocol or inherit those methods from a class that adopts it.  In the example above, MyClass must implement the methods in the AffiliationRequests and Normalization protocols and, in addition, either inherit from a class that adopts the Joining protocol or implement the Joining methods itself.
When these conventions are followed and all the methods in adopted and incorporated protocols are in fact implemented, the **conformsToProtocol:** test for a set of methods becomes roughly equivalent to the **respondsToSelector:** test for a single method.
However, **conformsToProtocol:** judges conformance solely on the basis of the formal declarations in source code, as illustrated above.  It doesn't check to see whether the methods declared in the protocol are actually implemented.  It's the programmer's responsibility to see that they are.
The Protocol object required as this method's argument can be specified using the **@protocol()** directive: |
![][1]BOOL canJoin = [MyClass conformsToProtocol:@protocol(Joining)];
| ----- |
| | **See also:**  ![][3] **conformsToProtocol:**
**description** |
| ----- |
| | \+ (NSString *)**description** |
| ----- |
| | Returns a string object that represents the contents of the receiver.  The debugger's **print-object** command invokes this method to produce a textual description of an object.
NSObject's implementation of this method simply prints the name of the class.
**See also:**  ![][3] **description**
**initialize** |
| ----- |
| | \+ **initialize** |
| ----- |
| | Initializes the class before it's used (before it receives its first message).  The run-time system sends an **initialize **message to each class just before the class, or any class that inherits from it, is sent its first message from within the program.  Each class object receives the **initialize** message just once.  Superclasses receive it before subclasses do.
For example, if the first message your program sends is this, |
![][1][Application new]
| ----- |
| | the run-time system will generate these three **initialize** messages, |
![][1][NSObject initialize];
![][1][Responder initialize];
![][1][Application initialize];
| ----- |
| | since Application is a subclass of Responder and Responder is a subclass of NSObject. All the **initialize** messages precede the **new** message and are sent in the order of inheritance, as shown.
If your program later begins to use the Text class, |
![][1][Text instancesRespondToSelector:someSelector]
| ----- |
| | the run-time system will generate these additional **initialize** messages, |
![][1][View initialize];
![][1][Text initialize];
| ----- |
| | since the Text class inherits from NSObject, Responder, and View. The **instancesRespondToSelector:** message is sent only after all these classes are initialized. Note that the **initialize** messages to NSObject and Responder aren't repeated; each class is initialized only once.
You can implement your own versions of **initialize** to provide class-specific initialization as needed.
Because **initialize** methods are inherited, it's possible for the same method to be invoked many times, once for the class that defines it and once for each inheriting class.  To prevent code from being repeated each time the method is invoked, it can be bracketed as shown in the example below: |
![][1]\+ initialize
![][1]{
![][1]if ( self == [MyClass class] ) {
![][1]/* _put initialization code here_ */
![][1]}
![][1]return self;
![][1]}
| ----- |
| | Since the run-time system sends a class just one **initialize** message, the test shown in the example above should prevent code from being invoked more than once.  However, if for some reason an application also generates **initialize **messages, a more explicit test may be needed: |
![][1]\+ initialize
![][1]{
![][1]static BOOL tooLate = NO;
![][1]if ( !tooLate ) {
![][1]/* _put initialization code here_ */
![][1]tooLate = YES;
![][1]}
![][1]return self;
![][1]}
| ----- |
| | **See also:**  ![][3] **init**, ![][3] **class** (NSObject protocol)
**instanceMethodForSelector:** |
| ----- |
| | \+ (IMP)**instanceMethodForSelector:**(SEL)_aSelector_ |
| ----- |
| | Locates and returns the address of the implementation of the _aSelector_ instance method.  An error is generated if instances of the receiver can't respond to _aSelector_ messages.
This method is used to ask the class object for the implementation of an instance method.  To ask the class for the implementation of a class method, use the instance method **methodForSelector:** instead of this one.
**instanceMethodForSelector:**, and the function pointer it returns, are subject to the same constraints as those described for **methodForSelector:**.
**See also:**  ![][3] **methodForSelector:**
**instancesRespondToSelector:** |
| ----- |
| | \+ (BOOL)**instancesRespondToSelector:**(SEL)_aSelector_ |
| ----- |
| | Returns YES if instances of the class are capable of responding to _aSelector_ messages, and NO if they're not.  To ask the class whether it, rather than its instances, can respond to a particular message, use the **respondsToSelector: **instance method instead of **instancesRespondToSelector:**.
If _aSelector_ messages are forwarded to other objects, instances of the class will be able to receive those messages without error even though this method returns NO.
**See also:**  ![][3] **respondsToSelector:**,  ![][3] **forwardInvocation:**
**load** |
| ----- |
| | \+ **load** |
| ----- |
| | Implemented by subclasses to integrate the class, or a category of the class, into a running program.  The NSObject implementation of this method simply returns **self**.
A **load** message is sent immediately after the class or category has been dynamically loaded into memory, but only if the newly loaded class or category implements a method that can respond.
Once a dynamically loaded class is used, it will also receive an **initialize** message.  However, because the **load **message is sent immediately after the class is loaded, it always precedes the **initialize** message, which is sent only when the class receives its first message from within the program.
A **load** method is specific to the class or category where it's defined; it's not inherited by subclasses or shared with the rest of the class.  Thus a class that has four categories can define a total of five **load** methods, one in each category and one in the main class definition.  The method that's performed is the one defined in the class or category just loaded.
**new** |
| ----- |
| | \+ **new** |
| ----- |
| | Allocates a new instance of the receiving class, sends it an **init** message, and returns the initialized object returned by **init**.
As defined in the NSObject class, **new** is a combination of **alloc** and **init**.  Like **alloc**, it initializes the **isa** instance variable of the new object so that it points to the class data structure.  It then invokes the **init** method to complete the initialization process.
Unlike **alloc**, **new** is sometimes reimplemented in subclasses to have it invoke a class-specific initialization method. If the **init** method includes arguments, they're typically reflected in the **new** method as well. For example: |
![][1]\+ newArg:(int)tag arg:(struct info *)data
![][1]{
![][1]return [[self alloc] initArg:tag arg:data];
![][1]}
| ----- |
| | However, there's little point in implementing a **new...** method if it's simply a shorthand for **alloc** and **init...**, like the one shown above.  Often **new...** methods will do more than just allocation and initialization.  In some classes, they manage a set of instances, returning the one with the requested properties if it already exists, allocating and initializing a new one only if necessary.  For example: |
![][1]\+ newArg:(int)tag arg:(struct info *)data
![][1]{
![][1]MyClass *theInstance;
![][1]if ( theInstance = findTheObjectWithTheTag(tag) )
![][1]return theInstance;
![][1]return [[self alloc] initArg:tag arg:data];
![][1]}
| ----- |
| | Although it's appropriate to define new **new...** methods in this way, the **alloc** and **allocWithZone:** methods should never be augmented to include initialization code.
**See also:**  ![][3] **init**, + **alloc**, + **allocWithZone:**
**poseAsClass** |
| ----- |
| | \+ **poseAsClass:**(Class)_aClassObject_ |
| ----- |
| | Causes the receiving class to "pose as" its superclass, the _aClassObject_ class. The receiver takes the place of _aClassObject_ in the inheritance hierarchy; all messages sent to _aClassObject_ will actually be delivered to the receiver. The receiver must be defined as a subclass of _aClassObject_. It can't declare any new instance variables of its own, but it can define new methods and override methods defined in the superclass. The **poseAsClass:** message should be sent before any messages are sent to _aClassObject_ and before any instances of _aClassObject_ are created.
This facility allows you to add methods to an existing class by defining them in a subclass and having the subclass substitute for the existing class.  The new method definitions will be inherited by all subclasses of the superclass.  Care should be taken to ensure that this doesn't generate errors.
A subclass that poses as its superclass still inherits from the superclass.  Therefore, none of the functionality of the superclass is lost in the substitution.  Posing doesn't alter the definition of either class.
Posing is useful as a debugging tool, but category definitions are a less complicated and more efficient way of augmenting existing classes.  Posing admits only two possibilities that are absent for categories: |
| ----- |
| | ![][2] | A method defined by a posing class can override any method defined by its superclass.  Methods defined in categories can replace methods defined in the class proper, but they cannot reliably replace methods defined in other categories.  If two categories define the same method, one of the definitions will prevail, but there's no guarantee which one. |
| - | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| | ![][2] | A method defined by a posing class can, through a message to **super**, incorporate the superclass method it overrides.  A method defined in a category can replace a method defined elsewhere by the class, but it can't incorporate the method it replaces. |
| ----- |
| | If successful, this method returns **self**.  If not, it generates an error message and aborts.
**setVersion** |
| ----- |
| | \+ (void)**setVersion:**(int)_anInt_ |
| ----- |
| | Sets the class version number to _anInt_, and returns **self**.  The version number is helpful when instances of the class are to be archived and reused later.  The default version is 0.
**See also:**  \+ **version**
**superclass** |
| ----- |
| | \+ **superclass** |
| ----- |
| | Returns the class object for the receiver's superclass.
**See also:**  \+ **class**, ![][3] **superclass**
**version** |
| ----- |
| | \+ (int)**version** |
| ----- |
| | Returns the version number assigned to the class.  If no version has been set, this will be 0.
**See also:**  \+ **setVersion:** |
| ----- |
| | **Instance Methods** |
| ----- |
| | **awakeAfterUsingCoder:** |
| ----- |
| | ![][3] **awakeAfterUsingCoder:**(NSCoder *)_aCoder_ |
| ----- |
| | This method is implemented by subclasses to reinitialize the receiver, providing one last chance for the object to propose another in its place. The NSObject implementation of this method simply returns **self**.
This method is necessary because an object (say an instance of a subclass **Font**) may decide to replace itself after all the **initWithCoder** messages have been processed, and the method deciding to replace maybe in the middle of the inheritance hierarchy (say, **Font**).
If a replacement takes place, the implementation of **awakeAfterUsingCoder:** is responsible for releasing the old self.
**See also:**  ![][3] **initWithCoder:**(NSCoding protocol)
**classForArchiver** |
| ----- |
| | ![][3] (Class)**classForArchiver** |
| ----- |
| | Identifies the class to be used during archiving. NSObject's implementation returns the object returned by **classForCoder:**.
**classForCoder** |
| ----- |
| | ![][3] (Class)**classForCoder** |
| ----- |
| | Identifies the class to be used during coding. An NSObject returns its own class by default.
**See also:**  ![][3] **class** (NSObject protocol)
**dealloc** |
| ----- |
| | ![][3] (void)**dealloc** |
| ----- |
| | Deallocates the memory occupied by the receiver. Subsequent messages to the object will generate an error indicating that a message was sent to a freed object (provided that the freed memory hasn't been reused yet).
You never send a **dealloc** message directly.  Instead, an object's **dealloc** method is invoked indirectly through the **release** method.  See the introduction to the Foundation Kit for more details on the use of these methods.
Subclasses must implement their own versions of **dealloc** to allow the deallocation of any additional memory consumed by the object--such as dynamically allocated storage for data, or other objects that are tightly coupled to the freed object and are of no use without it.  After performing the class-specific deallocation, the subclass method should incorporate superclass versions of **dealloc** through a message to **super**: |
![][1]\- dealloc {
![][1][companion release];
![][1]free(privateMemory);
![][1]vm_deallocate(task_self(), sharedMemory, memorySize);
![][1][super dealloc];
![][1]}
| ----- |
| | **See also:**  ![][3] **release** (NSObject protocol), ![][3] **autorelease** (NSObject protocol)
**description** |
| ----- |
| | ![][3] (NSString *)**description** |
| ----- |
| | Returns a string object that represents the contents of the receiver.  The debugger's **print-object** command invokes this method to produce a textual description of an object.
NSObject's implementation of this method simply prints the name of the receiver's class and the hexadecimal value of its **id**.
**See also:**  \+ **description**
**doesNotRecognizeSelector:** |
| ----- |
| | ![][3] (void)**doesNotRecognizeSelector:**(SEL)_aSelector_ |
| ----- |
| | Handles _aSelector_ messages that the receiver doesn't recognize.  The run-time system invokes this method whenever an object receives an _aSelector_ message that it can't respond to or forward.  This method, in turn, raises an NSInvalidArgumentException exception, and generates an error message.
**doesNotRecognizeSelector:** messages are generally sent only by the run-time system. However, they can be used in program code to prevent a method from being inherited. For example, an NSObject subclass might renounce the **copy **method by reimplementing it to include a **doesNotRecognizeSelector:** message as follows: |
![][1]\- copy
![][1]{
![][1][self doesNotRecognizeSelector:_cmd];
![][1]}
| ----- |
| | This code prevents instances of the subclass from recognizing or forwarding **copy** messages--although the **respondsToSelector:** method will still report that the receiver has access to a **copy** method.
(The **_cmd** variable identifies the current selector; in the example above, it identifies the selector for the **copy** method.)
**See also:**  ![][3] **forwardInvocation:**
**forwardInvocation:** |
| ----- |
| | ![][3] (void)**forwardInvocation:**(NSInvocation *)_anInvocation_ |
| ----- |
| | Implemented by subclasses to forward messages to other objects. When an object is sent a message for which it has no corresponding method, the run-time system gives the receiver an opportunity to delegate the message to another receiver. It does this by creating an NSInvocation object representing the message and sending the receiver a **forwardInvocation:** message containing this NSInvocation as the argument. The receiver's **forwardInvocation: **method can then choose to forward the message to another object. (If the delegated receiver can't respond to the message either, it too will be given a chance to forward it.)
The **forwardInvocation:** message thus allows an object to establish relationships with other objects that will, for certain messages, act on its behalf.  The forwarding object is, in a sense, able to "inherit" some of the characteristics of the object it forwards the message to.
A **forwardInvocation:** message is generated only if the message encoded in _anInvocation_ isn't implemented by the receiving object's class or by any of the classes it inherits from.
An implementation of the **forwardInvocation:** method has two tasks: |
| ----- |
| | ![][2] | To locate an object that can respond to the message encoded in _anInvocation_.  This need not be the same object for all messages. |
| - | ------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| | ![][2] | To dispatch the message to that object. |
| ----- |
| | In the simple case, in which an object forwards messages to just one destination (such as the hypothetical **friend **instance variable in the example below), a **forwardInvocation:** method could be as simple as this: |
![][1]\- (void)forwardInvocation:(NSInvocation *)invocation
![][1]{
![][1]if ([friend respondsToSelector:[invocation selector]]) {
![][1][invocation setTarget:friend];
![][1][invocation dispatch];
![][1]}
![][1][self doesNotRecognizeSelector:aSelector];
![][1]}
| ----- |
| | The message that's forwarded must have a fixed number of arguments; variable numbers of arguments (in the style of **printf()**) are not supported.
The return value of the message that's forwarded is returned to the original sender.  All types of return values can be delivered to the sender: **id**s, structures, double-precision floating point numbers.
Implementations of the **forwardInvocation:** method can do more than just forward messages.  **forwardInvocation: **can, for example, be used to consolidate code that responds to a variety of different messages, thus avoiding the necessity of having to write a separate method for each selector.  A **forwardInvocation:** method might also involve several other objects in the response to a given message, rather than forward it to just one.
The default version of **forwardInvocation:** implemented in the NSObject class simply invokes the **doesNotRecognizeSelector:** method; it doesn't forward messages.  Thus, if you choose not to implement **forwardInvocation:**, unrecognized messages will generate an error and cause the task to abort.
**Note:**  If it's necessary for a **forwardInvocation:** method to reason about or modify the arguments passed in _anInvocation_, it can do so through the methods declared by the NSInvocation class.
**See also:**  ![][3] **doesNotRecognizeSelector:**
**hash** |
| ----- |
| | @protocol NSObject
![][3] (unsigned int)**hash** |
| ----- |
| | Returns an unsigned integer that can be used as a table address in a hash table structure. For NSObject, **hash** returns a value based on the object's **id**. If two objects are equal (as determined by the **isEqual:** method), they will have the same hash value.This last point is particularly important if you define **hash** in a subclass and intend to put instances of that subclass into a collection.
**See also:**  ![][3] **isEqual:** (NSObject protocol)
**init** |
| ----- |
| | ![][3] **init** |
| ----- |
| | Implemented by subclasses to initialize a new object (the receiver) immediately after memory for it has been allocated. An **init** message is generally coupled with an **alloc** or **allocWithZone:** message in the same line of code: |
![][1]TheClass *newObject = [[TheClass alloc] init];
| ----- |
| | An object isn't ready to be used until it has been initialized.  The version of the **init** method defined in the NSObject class does no initialization; it simply returns **self**.
Subclass versions of this method should return the new object (**self**) after it has been successfully initialized.  If it can't be initialized, they should free the object and return **nil**.  In some cases, an **init** method might free the new object and return a substitute.  Programs should therefore always use the object returned by **init**, and not necessarily the one returned by **alloc** or **allocWithZone:**, in subsequent code.
Every class must guarantee that the **init** method returns a fully functional instance of the class.  Typically this means overriding the method to add class-specific initialization code.  Subclass versions of **init** need to incorporate the initialization code for the classes they inherit from, through a message to **super**: |
![][1]\- init
![][1]{
![][1][super init];
![][1]/* _class-specific initialization goes here_ */
![][1]return self;
![][1]}
| ----- |
| | Note that the message to **super** precedes the initialization code added in the method.  This ensures that initialization proceeds in the order of inheritance.
Subclasses often add arguments to the **init** method to allow specific values to be set.  The more arguments a method has, the more freedom it gives you to determine the character of initialized objects.  Classes often have a set of **init... **methods, each with a different number of arguments.  For example: |
![][1]\- init;
![][1]\- initArg:(int)tag;
![][1]\- initArg:(int)tag arg:(struct info *)data;
| ----- |
| | The convention is that at least one of these methods, usually the one with the most arguments, includes a message to **super** to incorporate the initialization of classes higher up the hierarchy.  This method is the _designated initializer_ for the class.  The other **init...** methods defined in the class directly or indirectly invoke the designated initializer through messages to **self**.  In this way, all **init...** methods are chained together.  For example: |
![][1]\- init
![][1]{
![][1]return [self initArg:-1];
![][1]}
![][1]\- initArg:(int)tag
![][1]{
![][1]return [self initArg:tag arg:NULL];
![][1]}
![][1]\- initArg:(int)tag arg:(struct info *)data
![][1]{
![][1][super init. . .];
![][1]/* _class-specific initialization goes here_ */
![][1]}
| ----- |
| | In this example, the **initArg:arg:** method is the designated initializer for the class.
If a subclass does any initialization of its own, it must define its own designated initializer.  This method should begin by sending a message to **super** to perform the designated initializer of its superclass.  Suppose, for example, that the three methods illustrated above are defined in the B class.  The C class, a subclass of B, might have this designated initializer: |
![][1]\- initArg:(int)tag arg:(struct info *)data arg:anObject
![][1]{
![][1][super initArg:tag arg:data];
![][1]/* _class-specific initialization goes here_ */
![][1]}
| ----- |
| | If inherited **init...** methods are to successfully initialize instances of the subclass, they must all be made to (directly or indirectly) invoke the new designated initializer.  To accomplish this, the subclass is obliged to cover (override) only the designated initializer of the superclass.  For example, in addition to its designated initializer, the C class would also implement this method: |
![][1]\- initArg:(int)tag arg:(struct info *)data
![][1]{
![][1]return [self initArg:tag arg:data arg:nil];
![][1]}
| ----- |
| | This ensures that all three methods inherited from the B class also work for instances of the C class.
Often the designated initializer of the subclass overrides the designated initializer of the superclass.  If so, the subclass need only implement the one **init...** method.
These conventions maintain a direct chain of **init...** links, and ensure that the **new** method and all inherited **init... **methods return usable, initialized objects.  They also prevent the possibility of an infinite loop wherein a subclass method sends a message (to **super**) to perform a superclass method, which in turn sends a message (to **self**) to perform the subclass method.
This **init** method is the designated initializer for the NSObject class.  Subclasses that do their own initialization should override it, as described above.
**See also:**  \+ **new**, + **alloc**, + **allocWithZone:**
**isEqual:** |
| ----- |
| | @protocol NSObject
![][3] (BOOL)**isEqual:**_anObject_ |
| ----- |
| | Returns YES if the receiver and _anObject_ are equal; otherwise returns NO. For NSObject, the **id** of _anObject_ and the receiver are compared to determine equality.
**methodForSelector:** |
| ----- |
| | ![][3] (IMP)**methodForSelector:**(SEL)_aSelector_ |
| ----- |
| | Locates and returns the address of the receiver's implementation of the _aSelector_ method, so that it can be called as a function.  If the receiver is an instance, _aSelector_ should refer to an instance method; if the receiver is a class, it should refer to a class method.
_aSelector_ must be a valid, non-NULL selector.  If in doubt, use the **respondsToSelector:** method to check before passing the selector to **methodForSelector:**.
IMP is defined as a pointer to a function that returns an **id** and takes a variable number of arguments (in addition to the two "hidden" arguments--**self** and **_cmd**\--that are passed to every method implementation): |
![][1]typedef id (*IMP)(id, SEL, ...);
| ----- |
| | This definition serves as a prototype for the function pointer that **methodForSelector:** returns. It's sufficient for methods that return an object and take object arguments. However, if the _aSelector_ method takes different argument types or returns anything but an **id**, its function counterpart will be inadequately prototyped. Lacking a prototype, the compiler will promote **float**s to **double**s and **char**s to **int**s, which the implementation won't expect. It will therefore behave differently (and erroneously) when called as a function than when performed as a method.
To remedy this situation, it's necessary to provide your own prototype.  In the example below, the declaration of the **test** variable serves to prototype the implementation of the **isEqual:** method.  **test** is defined as pointer to a function that returns a BOOL and takes an **id** argument (in addition to the two "hidden" arguments).  The value returned by **methodForSelector:** is then similarly cast to be a pointer to this same function type: |
![][1]BOOL (*test)(id, SEL, id);
![][1]test = (BOOL (*)(id, SEL, id))[target
![][1]methodForSelector:@selector(isEqual:)];
![][1]while ( !test(target, @selector(isEqual:), someObject) ) {
![][1]. . .
![][1]}
| ----- |
| | In some cases, it might be clearer to define a type (similar to IMP) that can be used both for declaring the variable and for casting the function pointer **methodForSelector:** returns. The example below defines the **EqualIMP** type for just this purpose: |
![][1]typedef BOOL (*EqualIMP)(id, SEL, id);
![][1]EqualIMP test;
![][1]test = (EqualIMP)[target methodForSelector:@selector(isEqual:)];
![][1]while ( !test(target, @selector(isEqual:), someObject) ) {
![][1]. . .
![][1]}
| ----- |
| | Either way, it's important to cast **methodForSelector:**'s return value to the appropriate function type. It's not sufficient to simply call the function returned by **methodForSelector:** and cast the result of that call to the desired type. This can result in errors.
Note that turning a method into a function by obtaining the address of its implementation "unhides" the **self** and **_cmd **arguments.
**See also:**  \+ **instanceMethodForSelector:**
**methodSignatureForSelector:** |
| ----- |
| | ![][3] (NSMethodSignature *)**methodSignatureForSelector:**(SEL)_aSelector_ |
| ----- |
| | Returns an NSMethodSignature object that contains a description of the _aSelector_ method, or nil if the _aSelector _method can't be found.  When the receiver is an instance, _aSelector_ should be an instance method; when the receiver is a class, it should be a class method.  This method is mostly used in the implementation of protocols.
**replacementObjectForArchiver:** |
| ----- |
| | ![][3] (id)**replacementObjectForArchiver:**(NSArchiver *)_anArchiver_ |
| ----- |
| | Allows an object to substitute another object for itself during archiving. NSObject's implementation returns the object returned by **replacementObjectForCoder:**.
**replacementObjectForCoder:** |
| ----- |
| | ![][3] **replacementObjectForCoder:**(NSCoder *)_encoder_ |
| ----- |
| | Allows an object to substitute another object for itself during coding. An _encoder_ value of **nil** indicates that nothing should be encoded. NSObject's implementation returns **self**. |
[1]: http://www.nextop.de/Images/sp.gif
[2]: http://www.nextop.de/Images/bullet1.gif
[3]: http://www.nextop.de/Images/c2D.gif