< Previous PageNext Page > Hide TOC

Assembling the Text System by Hand

The vast majority of applications interact with the text system at a high level through one class: NSTextView. It is also possible to build the network of objects that make up the text system from the bottom up, starting with the NSTextStorage object. Understanding how this is done helps illuminate the design of the text-handling system.

In creating the text-handling network by hand, you create four objects but then release three as they are added to the network. You are left with a reference only to the NSTextStorage object. The NSTextView is retained, however, by both its NSTextContainer and its superview; to fully destroy this group of text objects you must send removeFromSuperview to the NSTextView object and then release the NSTextStorage object.

An NSTextStorage object is conceptually the owner of any network of text objects, no matter how complex. When you release the NSTextStorage object, it releases its NSLayoutManagers, which release their NSTextContainers, which in turn release their NSTextViews.


Figure 1  Text System Memory Management

Text System Memory Management

However, recall that the text system implements a simplified ownership policy for those whose only interaction with the system is through the NSTextView class. See “Creating an NSTextView Programmatically” for more information.

Contents:

Set Up an NSTextStorage Object
Set Up an NSLayoutManager Object
Set Up an NSTextContainer Object
Set Up an NSTextView Object


Set Up an NSTextStorage Object

You create an NSTextStorage object in the normal way, using the alloc and init... messages. In the simplest case, where there’s no initial contents for the NSTextStorage, the initialization looks like this:

textStorage = [[NSTextStorage alloc] init];

If, on the other hand, you want to initialize an NSTextStorage object with rich text data from a file, the initialization looks like this (assume filename is defined):

textStorage = [[NSTextStorage alloc]
    initWithRTF:[NSData dataWithContentsOfFile:filename]
    documentAttributes:NULL];

We’ve assumed that textStorage is an instance variable of the object that contains this method. When you create the text-handling system by hand, you need to keep a reference only to the NSTextStorage object as you’ve done here. The other objects of the system are owned either directly or indirectly by this NSTextStorage object, as you’ll see in the next steps.

Set Up an NSLayoutManager Object

Next, create an NSLayoutManager object:

NSLayoutManager *layoutManager;
layoutManager = [[NSLayoutManager alloc] init];
[textStorage addLayoutManager:layoutManager];
[layoutManager release];

Note that layoutManager is released after being added to textStorage. This is because the NSTextStorage object retains each NSLayoutManager that’s added to it—that is, the NSTextStorage object owns its NSLayoutManagers.

The NSLayoutManager needs a number of supporting objects—such as those that help it generate glyphs or position text within a text container—for its operation. It automatically creates these objects (or connects to existing ones) upon initialization. You only need to connect the NSLayoutManager to the NSTextStorage object and to the NSTextContainer object, as seen in the next step.

Set Up an NSTextContainer Object

Next, create an NSTextContainer and initialize it with a size. Assume that theWindow is defined and represents the window that displays the text view.

NSRect cFrame = [[theWindow contentView] frame];
NSTextContainer *container;
 
container = [[NSTextContainer alloc]
    initWithContainerSize:cFrame.size];
[layoutManager addTextContainer:container];
[container release];

Once you’ve created the NSTextContainer, you add it to the list of containers that the NSLayoutManager owns, and then you release it. The NSLayoutManager now owns the NSTextContainer and is responsible for releasing it when it’s no longer needed. If your application has multiple NSTextContainers, you can create them and add them at this time.

Set Up an NSTextView Object

Finally, create the NSTextView (or NSTextViews) that displays the text:

NSTextView *textView = [[NSTextView alloc]
initWithFrame:cFrame textContainer:container];
[theWindow setContentView:textView];
[theWindow makeKeyAndOrderFront:nil];
[textView release];

Note that initWithFrame:textContainer: is used to initialize the NSTextView. This initialization method does nothing more than what it says: initialize the receiver and set its text container. This is in contrast to initWithFrame:, which not only initializes the receiver, but creates and interconnects the network of objects that make up the text-handling system. Once the NSTextView has been initialized, it’s added to the window, which is then displayed. Finally, you release the NSTextView.



< Previous PageNext Page > Hide TOC


© 1997, 2009 Apple Inc. All Rights Reserved. (Last updated: 2009-04-08)


Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.