您的位置:首页 > 移动开发 > Objective-C

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.


二、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 is
the 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 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




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




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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: