Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
8.64 Mб

Objects in memory

Objects in memory

Figure 12.3 is an object diagram. This diagram shows two NSDate instances on the heap. The two variables now and later are part of the frame for the function main(). They point to the NSDate objects, as shown by the arrows.

Figure 12.3 Object diagram for TimeAfterTime

You’ve only seen one class thus far: NSDate. There are, in fact, hundreds of classes that come with iOS and Mac OS X. We’ll work with some of the more common ones in the coming chapters.


When declaring a pointer to hold on to an object, most of the time you specify the class of the object that the pointer will refer to:

NSDate *expiration;

However, often you need a way to create a pointer without knowing exactly what kind of object the pointer will refer to. For this case, we use the type id to mean “a pointer to some kind of Objective-C object” Here is what it looks like when you use it:

id delegate;

Notice that there is no asterisk in this declaration. id implies the asterisk.

The ideas of classes, objects, messages, and methods can be difficult to get your head around at the beginning. Don’t worry if you're feeling a little uncertain about objects. This is just the beginning. You’ll be using these patterns over and over again, and they will make more sense each time you do.


Chapter 12 Objects


Use two instances of NSDate to figure out how many seconds you have been alive. Hint: here is how you create a new date object from the year, month, etc.:

NSDateComponents *comps = [[NSDateComponents alloc] init]; [comps setYear:1969];

[comps setMonth:4]; [comps setDay:30]; [comps setHour:13]; [comps setMinute:10]; [comps setSecond:0];

NSCalendar *g = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDate *dateOfBirth = [g dateFromComponents:comps];

To get the number of seconds between two instances of NSDate, use the method timeIntervalSinceDate:.

double d = [laterDate timeIntervalSinceDate:earlierDate];



More Messages

In the last chapter, you sent a few messages. Let’s look again at the lines where you sent those messages and triggered the corresponding methods:

NSDate *now = [NSDate date];

We say that the date method is a class method. That is, you cause the method to execute by sending a message to the NSDate class. The date method returns a pointer to an instance of NSDate.

double seconds = [now timeIntervalSince1970];

We say that timeIntervalSince1970 is an instance method. You cause the method to execute by sending a message to an instance of the class. The timeIntervalSince1970 method returns a double.

NSDate *later = [now dateByAddingTimeInterval:100000];

dateByAddingTimeInterval: is another instance method. This method takes one argument. You can determine this by the colon in the method name. This method also returns a pointer to an instance of


Nesting message sends

There is a class method alloc that returns a pointer to a new object that needs to be initialized. That pointer is then used to send the new object the message init. Using alloc and init is the most common way to create objects in Objective-C. It is good practice (and the only Apple-approved way) to send both of these messages in one line of code by nesting the message sends:

[[NSDate alloc] init];

The system will execute the messages on the inside first and then the messages that contain them. So, alloc is sent to the NSDate class, and the result of that (a pointer to the newly-created instance) is then sent init.

init returns a pointer to the new object (which is nearly always the pointer that came out of the alloc method), so we can use what’s returned from init for the assignment. Try out these nested messages in your code by changing the line:

NSDate *now = [NSDate date];


NSDate *now = [[NSDate alloc] init];


Chapter 13 More Messages

Multiple arguments

Some methods take several arguments. For example, an NSDate object doesn’t know what day of the month it is. If you needed this information, you would use an NSCalendar object. The NSCalendar method that can tell you the day of the month takes three arguments. Create an NSCalendar object and use it in main.m:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])


@autoreleasepool {

NSDate *now = [[NSDate alloc] init];

NSLog(@"The date is %@", now);

double seconds = [now timeIntervalSince1970];

NSLog(@"It has been %f seconds since the start of 1970.", seconds);

NSDate *later = [now dateByAddingTimeInterval:100000];

NSLog(@"In 100,000 seconds it will be %@", later);

NSCalendar *cal = [NSCalendar currentCalendar]; NSUInteger day = [cal ordinalityOfUnit:NSDayCalendarUnit


forDate:now]; NSLog(@"This is day %lu of the month", day);


return 0;


The method’s name is ordinalityOfUnit:inUnit:forDate:, and it takes three arguments. You can tell because the method name includes three colons. Notice that I split that message send into three lines. This is fine; the compiler does not mind the extra whitespace. Objective-C programmers

typically line up the colons so that it is easy to tell the parts of the method name from the arguments. (Xcode should do this for you: every time you start a new line, the previous line should indent properly. If that isn’t happening, check your Xcode preferences for indention.)

The first and second arguments of this method are the constants NSDayCalendarUnit and NSMonthCalendarUnit. These constants are defined in the NSCalendar class. They tell the method that you want to know what day it is within the month. The third argument is the date you want to know about.

If you wanted to know the hour of the year instead of the day of the month, you’d use these constants:

NSUInteger hour = [cal ordinalityOfUnit:NSHourCalendarUnit inUnit:NSYearCalendarUnit forDate:now];

Sending messages to nil

Nearly all object-oriented languages have the idea of nil, the pointer to no object. In Objective-C, nil is the zero pointer (same as NULL, which was discussed in Chapter 8).

In most object-oriented languages, sending a message to nil is not allowed. As a result, you have to check for non-nil-ness before accessing an object. So you see this sort of thing a lot:


Тут вы можете оставить комментарий к выбранному абзацу или сообщить об ошибке.

Оставленные комментарии видны всем.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]