Cocoa Programming for Mac OS X 第三章(Objective-C)摘录
2011-08-20 11:26
447 查看
一、
A Foundation Tool has no graphical user interface and typically runs on the command line or
in the background as a daemon. Unlike in an application project, you will always alter the main function
of a Foundation Tool.
In the toolbar, you will see a pop-up for the Active Build Configuration.
There are two choices: Debug and Release.
While working on your application, you will always want to be in Debug. Before you ship your application,
you will do a Release build. How are they different? A Release build
is universal and has had its debugging symbols stripped. Thus, the Release build
takes about twice as long to compile and has none of the stuff that the debugger needs to do its job.
In most object-oriented languages, your program will crash if you send a message to nil.
In applications written in those languages, you will see many checks for nil before
sending a message. In Java, for example, you frequently see the following:
In Objective-C, it is okay to send a message to nil.
The message is simply discarded, which eliminates the need for these sorts of checks. For example, this code will build and run without an error:
This approach is different from how most languages work, but you will get used to it.
You may find yourself asking over and over, "Argg! Why isn't this method getting called?" Chances are, the pointer you are using, assuming it is not nil,
is actually nil.
In the preceding example, what is bar set
to? Zero. If bar were a pointer,
it would be set to nil (zero for pointers). For other types, the value is less predictable.
NSObject is
the root of the entire Objective-C class hierarchy. Some commonly used methods on NSObject are
described next.
Initializes the receiver after memory for it has been allocated. An init message
is generally coupled with an allocmessage in
the same line of code:
Returns an NSString that
describes the receiver. The debugger's print object command ("po") invokes this method. A good description method
will often make debugging easier. Also, if you use %@ in a format string, the object
that should be substituted in is sent the message description.
The value returned by the description method
is put into the log string. For example, in your main function, the line
is equivalent to
Returns YES if the receiver and anObject are
equal and NO otherwise. You might use it like this:
But what does equal really mean? In NSObject,
this method is defined to return YES if
and only if the receiver andanObject are
the same object—that is, if both are pointers to the same memory location.
Clearly, this is not always the equal that
you would hope for, so this method is overridden by many classes to implement a more appropriate idea of equality. For example, NSString overrides
the method to compare the characters in the receiver and anObject.
If they have the same characters in the same order, the two strings are considered equal.
Thus, if x and y are NSStrings,
there is a big difference between these two expressions:
and
The first expression compares the two pointers. The second expression compares the characters in the strings. Note, however, that if x and y are
instances of a class that has not overridden NSObject's isEqual: method,
the two expressions are equivalent.
As mentioned earlier, an object is like a C struct. NSObject declares
an instance variable called isa. Because NSObject is
the root of the entire class-inheritance tree, every object has an isa pointer
to the class structure that created the object (Figure 3.15).
The class structure includes the names and types of the instance variables
for the class, as well as the implementation of the class's methods. The class structure has a pointer to the class structure for its superclass.
Figure 3.15. Each Object Has a Pointer to Its Class
![](http://hi.csdn.net/attachment/201108/20/0_1313810783jP11.gif)
The methods are indexed by the selector. The selector is of type SEL.
Although SEL is defined to be char
*, it is most useful to think of it as an int.
Each method name is mapped to a unique int. For example, the method name addObject: might
map to the number 12. When you look up methods, you will use the selector, not the string @"addObject:".
As part of the Objective-C data structures, a table maps the names of methods to their selectors. Figure
3.16 shows an example.
Figure 3.16. The Selector Table
![](http://hi.csdn.net/attachment/201108/20/0_13138107881ohj.gif)
At compile time, the compiler looks up the selectors wherever it sees a message send. Thus,
becomes (assuming that the selector for addObject: is
12)
Here, objc_msgSend() looks
at myObject's isa pointer
to get to its class structure and looks for the method associated with 12. If it does not find the method, it follows the pointer to the superclass. If the superclass does not have a method for 12, it continues searching up the tree. If it reaches the top
of the tree without finding a method, the function throws an exception.
Clearly, this is a very dynamic way of handling messages. These class structures can be changed at runtime. In particular, using the NSBundle class
makes it relatively easy to add classes and methods to your program while it is running. This very powerful technique has been used to create applications that can be extended by other developers.
A Foundation Tool has no graphical user interface and typically runs on the command line or
in the background as a daemon. Unlike in an application project, you will always alter the main function
of a Foundation Tool.
In the toolbar, you will see a pop-up for the Active Build Configuration.
There are two choices: Debug and Release.
While working on your application, you will always want to be in Debug. Before you ship your application,
you will do a Release build. How are they different? A Release build
is universal and has had its debugging symbols stripped. Thus, the Release build
takes about twice as long to compile and has none of the stuff that the debugger needs to do its job.
二、Sending Messages to nil
In most object-oriented languages, your program will crash if you send a message to nil.In applications written in those languages, you will see many checks for nil before
sending a message. In Java, for example, you frequently see the following:
if (foo != null) { foo.doThatThingYouDo(); }
In Objective-C, it is okay to send a message to nil.
The message is simply discarded, which eliminates the need for these sorts of checks. For example, this code will build and run without an error:
id foo; foo = nil; int bar = [foo count];
This approach is different from how most languages work, but you will get used to it.
You may find yourself asking over and over, "Argg! Why isn't this method getting called?" Chances are, the pointer you are using, assuming it is not nil,
is actually nil.
In the preceding example, what is bar set
to? Zero. If bar were a pointer,
it would be set to nil (zero for pointers). For other types, the value is less predictable.
三、NSObject
NSObject isthe root of the entire Objective-C class hierarchy. Some commonly used methods on NSObject are
described next.
- (id)init
Initializes the receiver after memory for it has been allocated. An init message
is generally coupled with an allocmessage in
the same line of code:
TheClass *newObject = [[TheClass alloc] init];
- (NSString *)description
Returns an NSString that
describes the receiver. The debugger's print object command ("po") invokes this method. A good description method
will often make debugging easier. Also, if you use %@ in a format string, the object
that should be substituted in is sent the message description.
The value returned by the description method
is put into the log string. For example, in your main function, the line
NSLog(@"The number at index %d is %@", i, numberToPrint);
is equivalent to
NSLog(@"The number at index %d is %@", i, [numberToPrint description]);
- (BOOL)isEqual:(id)anObject
Returns YES if the receiver and anObject are
equal and NO otherwise. You might use it like this:
if ([myObject isEqual:anotherObject]) { NSLog(@"They are equal."); }
But what does equal really mean? In NSObject,
this method is defined to return YES if
and only if the receiver andanObject are
the same object—that is, if both are pointers to the same memory location.
Clearly, this is not always the equal that
you would hope for, so this method is overridden by many classes to implement a more appropriate idea of equality. For example, NSString overrides
the method to compare the characters in the receiver and anObject.
If they have the same characters in the same order, the two strings are considered equal.
Thus, if x and y are NSStrings,
there is a big difference between these two expressions:
x == y
and
[x isEqual:y]
The first expression compares the two pointers. The second expression compares the characters in the strings. Note, however, that if x and y are
instances of a class that has not overridden NSObject's isEqual: method,
the two expressions are equivalent.
四、How Does Messaging Work?
As mentioned earlier, an object is like a C struct. NSObject declaresan instance variable called isa. Because NSObject is
the root of the entire class-inheritance tree, every object has an isa pointer
to the class structure that created the object (Figure 3.15).
The class structure includes the names and types of the instance variables
for the class, as well as the implementation of the class's methods. The class structure has a pointer to the class structure for its superclass.
Figure 3.15. Each Object Has a Pointer to Its Class
![](http://hi.csdn.net/attachment/201108/20/0_1313810783jP11.gif)
The methods are indexed by the selector. The selector is of type SEL.
Although SEL is defined to be char
*, it is most useful to think of it as an int.
Each method name is mapped to a unique int. For example, the method name addObject: might
map to the number 12. When you look up methods, you will use the selector, not the string @"addObject:".
As part of the Objective-C data structures, a table maps the names of methods to their selectors. Figure
3.16 shows an example.
Figure 3.16. The Selector Table
![](http://hi.csdn.net/attachment/201108/20/0_13138107881ohj.gif)
At compile time, the compiler looks up the selectors wherever it sees a message send. Thus,
[myObject addObject:yourObject];
becomes (assuming that the selector for addObject: is
12)
objc_msgSend(myObject, 12, yourObject);
Here, objc_msgSend() looks
at myObject's isa pointer
to get to its class structure and looks for the method associated with 12. If it does not find the method, it follows the pointer to the superclass. If the superclass does not have a method for 12, it continues searching up the tree. If it reaches the top
of the tree without finding a method, the function throws an exception.
Clearly, this is a very dynamic way of handling messages. These class structures can be changed at runtime. In particular, using the NSBundle class
makes it relatively easy to add classes and methods to your program while it is running. This very powerful technique has been used to create applications that can be extended by other developers.
相关文章推荐
- Cocoa Programming for Mac OS X 第十六章(Localization)摘录
- Objective-C(Chapter 3 of Cocoa Programming for Mac OS X)
- Cocoa Programming for Mac OS X 第一章(What Is It?)摘录
- Cocoa Programming for Mac OS X 第十八章(Images and Mouse Events)摘录
- Cocoa Programming for Mac OS X 第二章(Let's Get Started)摘录
- Cocoa Programming for Mac OS X 第四章(Memory Management)摘录
- Cocoa Programming for Mac OS X 第十三章(User Defaults)摘录
- Cocoa Programming for Mac OS X 第七章(Key-Value Coding; Key-Value Observing)摘录
- Cocoa Programming for Mac OS X 第十五章(Using Alert Panels)摘录
- Core Data Relationships(Chapter 30 of Cocoa Programming for Mac OS X)
- Memory Management(Chapter 4 of Cocoa Programming for Mac OS X)
- NSUndoManager(Chapter 9 of Cocoa Programming for Mac OS X)
- NSTimer(Chapter 24 of Cocoa Programming for Mac OS X)
- Basic Core Data(Chapter 11 of Cocoa Programming for Mac OS X)
- Keyboard Events(Chapter 19 of Cocoa Programming for Mac OS X)
- Drawing Text With Attributes(Chapter 20 of Cocoa Programming for Mac OS X)
- Pasteboards and Nil-Targeted Actions(Chapter 21 of Cocoa Programming for Mac OS X)
- Creating NSFormatters(Chapter 26 of Cocoa Programming for Mac OS X)
- Helper Objects (Chapter 6 of Cocoa Programming for Mac OS X)
- Key-Value Coding, Key-Value observing(Chapter 7 of Cocoa Programming for Mac OS X)