Anonymous Type and Heterogeneous Containers
Objective-C defines the type id, which is known as the Anonymous Type. The id type tells the compiler that a variable pointss to an object but doesn't give the compiler any more specific information about the kind of object, hence the object is anonymous.
Motivation
Use the Anonymous Type pattern to send messages to anonymous objects, including objects that are not available at the time the sending code is compiled. Reduce coiuplig between classes by limiting the information that each class has about oter classes. Use Heterogeneous Containers to provide powerful container classes that can each store any number of objects of any type in any combination.
Soulution
Messaging is flexible and dynamic because both the receiver and the selector are variables.
The determination of exactly which message is sent to which receiver is deferred
until a program is running.At the time a program is compiled, it’s not always possible to
know the type of object that will receive the message. Many other object-oriented languages
such as C++ and Java require that the type of every object is known to the compiler.
Objective-C has no such requirement.
In C any pointer can store the constant NULL, which equals 0. In Objective-C, any
pointer to an object can store the constant nil, which also equals 0. Messages sent to nil
are not always errors as they would be in Ruby or Java. In Objective-C, such messages immediately
return nil.
Don’t rely on the value returned from a message to nil unless the message is expected to
return a pointer or a type convertible to a pointer. For example, messages that return float
or a structure have an undefined return value when sent to nil.
To declare a pointer to an instance of a specific class, use the class name as a type. For
example, to declare a reference to an instance of Cocoa’s NSArray class, use the following
syntax:
NSArray *anArray;
Objective-C allows the forward declaration of class names using the @class compiler
directive.The following declarations tell the compiler that NSArray, NSDictionary, and
NSNumber are all the names of classes that have yet to be defined:
@class NSArray;
@class NSDictionary, NSNumber;
Use forward declaration of class names in the same situations as when standard C structures
are forward declared, such as solving circular import dependency problems. In particular,
forward declaration of classes is used in class interface declarations so that two or
more classes can refer to each other without error as follows:
@class MYAcademicStatus
@interface MYStudentRecord : NSObject
{
MYAcademicStatus *currentStatus;
}
@end
Use forward declaration of class names in the same situations as when standard C structures
are forward declared, such as solving circular import dependency problems. In particular,
forward declaration of classes is used in class interface declarations so that two or
more classes can refer to each other without error as follows:
@class MYAcademicStatus @interface MYStudentRecord : NSObject { MYAcademicStatus *currentStatus; } @end @interface MYAcademicStatus : NSObject { BOOL isEnroled; MYStudentRecord *record; } @end
The id type can be used instead of specific class names when declaring object instance
variables.The MYStudentRecord and MYAcademicStatus classes could have been declared
as follows without the need for the forward declaration of any class name, but the compiler
would have less information to use when compiling the code:
@interface MYStudentRecord : NSObject { id currentStatus; } @end @interface MYAcademicStatus : NSObject { BOOL isEnroled; id record; } @end
Regardless of whether the Anonymous Type or a more specific object type is used, any
message can be sent to any object. Providing information to the compiler beyond the information
conveyed by id enables the compiler to generate warnings when it can’t verify
that a receiver responds to a message.Warnings are generated instead of errors because the
compiler can never be sure that the receiver doesn’t respond to a message. It’s possible that
the method to respond to a particular message exists but is not known to the compiler.
That happens when methods are implemented in a class implementation but not declared
in a class interface. It also may happen when methods are added to a class with a
Category that is dynamically loaded at runtime.
If a receiver doesn’t respond to a message sent at runtime and no special processing is
used to forward the message to another receiver, a runtime error occurs.This is often
considered a bug of the same severity as an application crash. In practice, errors are e
avoided because it is possible to determine at runtime whether a particular receiver can
respond to a particular message before the message is sent. Cocoa’s NSObject class provides
the –(BOOL)respondsToSelector:(SEL)aSelector method that returns YES if the
receiver responds to a specified selector and NO otherwise.The -respondsToSelector:
method is inherited by virtually every Cocoa class.
The objc.h header file is not strictly part of Cocoa. It’s a component of the
Objective-C runtime environment that is provided as part of the underlying open source
Darwin operating system used by Mac OS X.
Assignment
Any variable of type id can be assigned to any pointer to an instance of a specific class as
follows:
id untypedObject; NSArray *anArray; // Assume untypedObject is initialized here anArray = untypedObject; // This assignment is OK
Similarly, a pointer to an instance of any class can be assigned to a variable of type id:
id untypedObject; NSArray *anArray; // Assume anArray is initialized here untypedObject = anArray; // This assignment is OK
If you want to verify at runtime that an assignment involving the Anonymous Type
makes sense, use the -isKindOfClass: method provided by NSObject:
id untypedObject; NSArray *anArray; // Assume untypedObject is initialized here // Verify that an assignment makes sense if([untypedObject isKindOfClass:[NSArray class]) { anArray = untypedObject; // This assignment is legal }
As an alternative to -(BOOL)isKindOfClass:(Class)aClass, the NSObject class also
provides - (BOOL)conformsToProtocol:(Protocol *)aProtocol.An Objective-C protocol
is a list of methods that an object promises to implement regardless of the inheritance
hierarchy of the class. In addition to the NSObject class, Cocoa provides an
NSObject protocol that declares the methods that almost every Cocoa class is expected to
provide.When possible, it is more flexible to test if an anonymous object conforms to a
protocol than to check if it inherits from a particular class.
It is possible to use protocols to get a compromise between anonymous and static typing.
For example, suppose we don’t care about an object’s class, but we do care that it conforms
to MYProtocol.We can define a variable in this way:
id <MYProtocol, NSObject> myProtocolObject;
By using id, myProtocolObject is still an anonymous type.The object to which it
points could be of any class(shoud conform to protocol??). But at the same time, the compiler knows what messages are
safe to send to the object, and it can emit a warning if an attempt is made to send a message
that is not in one of the listed protocols.
Heterogeneous Containers
Cocoa provides a small number of collection classes designed to meet most application
needs. Each collection is designed to store variables of type id. As a result, the collections
are called heterogeneous, meaning that references to objects of any type can be stored in any
combination.The collection classes automatically reserve extra storage as needed to hold
as many objects as required.
The collection classes are implemented in both mutable and immutable forms.The
contents stored by mutable collections can be changed throughout the execution of a
program. Immutable collections are created with particular contents, and the contents do
not change.
The NSArray and NSMutableArray classes store ordered collections of object references.
The NSDictionary and NSMutableDictionary classes store associations of keys
and values for rapid retrieval.The NSSet and NSMutableSet classes store unordered collections
of unique object references; each object can be referenced at most once in any
particular set. Finally, NSCountedSet, a subclass of NSMutableSet, provides an unordered
collection, but it allows multiple references to the same object within one collection.
The collection classes are all provided in Cocoa’s Foundation framework.The classes
are used extensively throughout Cocoa and can be adapted to almost any need.
Examples
"Outlets,Targets, and Actions,” use the Anonymous Type
to avoid coupling between user interface objects and custom objects so that both can be
reused with maximum flexibility.
Consequence pp84
One of the benefits of Objective-C’s Anonymous Type is the simplicity that it enables.
Objective-C provides a rich object-oriented infrastructure with minimal additions to the
base C language in part because of the Anonymous Type.The Anonymous Type eliminates
the need for complex language features like C++ templates and Ada generic packages.
When used with other patterns, the Anonymous Type can dramatically reduce the
amount of code needed to solve common problems.The Anonymous Type also promotes
loose coupling of code.
Objective-C’s Anonymous Type and messaging make it possible for Proxies and
Forwarding (Chapter 27) to provide an elegant solution for remote messaging without
unwieldy language extensions.?
posted on 2013-02-21 22:54 Chansonyan 阅读(274) 评论(0) 收藏 举报