Loading from a File

Loading means that there is already a file on the computer’s disk that we want to read and use in an application. Writing the code to load a file is usually considerably easier than writing the code to save it, because the hard work of figuring out which instance variables to save and getting them on the disk has (presumably) already been done.

A user can load a file into the MathPaper application by doing any of the following:

  • Choosing MathPaper’s File Open menu command and specifying a file in the Open panel

  • Choosing a file from MathPaper’s File Open Recent submenu

  • Double-clicking a MathPaper document file icon in the Finder

  • Dragging a MathPaper document on top of the MathPaper.app application icon and dropping it

The NSDocument framework handles all of these file-opening techniques for us automatically! All we need to do is to implement a single method called loadDataRepresentation:ofType: .

  1. Insert the following loadDataRepresentation:ofType method into the implementation of the MathController class in the file MathController.m:

                         - (BOOL)loadDataRepresentation:(NSData *)newHistory
                                                 ofType:(NSString *)aType
                         {
                             if ([aType isEqualToString:@"MathPaper"]) {
                                 MathDocument *temp;
                                 temp = [NSUnarchiver unarchiveObjectWithData:newHistory];
                                 if (temp) {
                                     [self setFrame:[temp frame] ];
                                     [self setHistory:[temp history] ];
                                     return YES;
                                 }
                             }
                             return NO;
                         }

When any of the actions described at the beginning of this section take place, the NSDocument architecture will open the requested file, copy the file’s data into the NSData object, and then pass this object and the document file type to our method. Our method makes sure that the NSData object is of the correct type. If it is, we ask the NSUnarchiver class to unarchive the NSData object into a temporary MathDocument object called temp. If the load is successful, the instance variables frame and history are set from the unarchived object. (We need to do this two-stage process because we decided to use the MathDocument class itself as the repository for the information in the document, rather than using a separate class created for that purpose.)

Unarchiving is the reverse of archiving: the NSUnarchiver class reads bytes from the NSData object and creates integers, floating-point values, and objects. Just as the NSArchiver class called the method encodeWithCoder: to perform the actual archiving, the NSUnarchiver class calls the method initWithCoder: to perform the actual unarchiving. Thus, in order to support unarchiving, we need to implement initWithCoder: as well.

  1. Insert the initWithCoder: method shown here before the @end directive in MathController.m:

                         - initWithCoder:(NSCoder *)coder
                         {
                             frame   = [coder decodeRect];
                             history = [[coder decodeObject] retain];
                             return self;
                         }

At this point, note the following important things. First, the MathPaper instance variables are decoded in the same order in which they were encoded. This is very important! If you’re trying to decode the variables in a different order, the decoding operation will generate an error. (In fact, an exception will be raised. You will not get corrupt data, as you might on other systems.)

Second, note that the history object is sent a retain message. Objects that are decoded are sent an autorelease message so that they will be freed when they are no longer needed; it is the responsibility of the class implementation to retain objects that are required for long-term use.

What happens if you save a MathPaper window in the upper-right corner when your screen resolution is set to something like 1280 x 1024, and then you attempt to read it back in at a different resolution, such as 1024 x 768? On some other operating systems, such as Microsoft Windows, you might discover that the window is “off the screen” and unusable. However, Cocoa looks at the size of the window whenever you call itssetFrame:display: method, and tries to keep windows on the computer’s screen.

  1. Compile and run your program. Try to open the files that you saved in the last section. The files should appear with the contents that they had when you saved them, and they should appear in the same places on the computer screen.

  2. Quit MathPaper.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.223.213.238