| < Previous PageNext Page > |
What makes a program a Cocoa program? It’s not really the language, because you can use a variety of languages in Cocoa development. It’s not the development tools, because you could create a Cocoa application from the command line (although that would be a complex, time-consuming task). No, what all Cocoa programs have in common—what makes them distinctive—is that they are composed of objects that inherit ultimately from the root class, NSObject, and that are ultimately based upon the Objective-C runtime. This statement is also true of all Cocoa frameworks.
Note: That statement also needs to be qualified a bit. First, Cocoa supplies another root class, NSProxy; however, NSProxy is rarely used in Cocoa programming. Second, you could create your own root class, but this would be a lot of work (entailing the writing of code that interacts with the Objective-C runtime) and probably not worth your time.
Mac OS X includes several Cocoa frameworks, and Apple and third-party vendors are releasing more frameworks all the time. Despite this abundance of Cocoa frameworks, two of them stand out from all the others. Foundation and Application Kit are the core Cocoa frameworks. You cannot develop a Cocoa application unless you link against (and use the classes of) the Application Kit. And you cannot develop Cocoa software of any type unless you link against and use the classes of the Foundation framework. (Linking against these frameworks happens automatically when you link against the Cocoa umbrella framework). The Foundation and Application Kit frameworks are essential to Cocoa development, and all other frameworks are secondary and elective.
The following sections surveys the features and classes of the two core Cocoa frameworks and briefly describes some of the secondary frameworks. To make these large frameworks more approachable, the introductions to the Foundation and Application Kit frameworks break down the dozens of classes in each hierarchy into functional groupings. Although these groupings have a strong logical basis, one can plausibly group classes in other ways.
Foundation
Application Kit
Other Frameworks With Cocoa API
The Foundation framework defines a base layer of classes that can be used for any type of Cocoa program. The criterion separating the classes in Foundation from those in the Application Kit is the user interface. If an object doesn’t either appear in a user interface or isn’t exclusively used to support a user interface, then its class belongs in Foundation. You can create Cocoa programs that use Foundation and no other framework; examples of these are command-line tools and Internet servers.
The Foundation framework was designed with certain goals in mind:
Define basic object behavior and introduce consistent conventions for such things as memory management, object mutability, and notifications.
Support internationalization and localization with (among other things) bundle technology and Unicode strings.
Support object persistence.
Support object distribution.
Provide some measure of operating-system independence to support portability.
Provide object wrappers or equivalents for programmatic primitives, such as numeric values, strings, and collections. Also include utility classes for accessing underlying system entities and services, such as ports, threads, and file systems.
Cocoa applications, which by definition link against the Application Kit, invariably must link against the Foundation framework as well. The class hierarchies share the same root class, NSObject, and many if not most of the Application Kit methods and functions have Foundation objects as parameters or return values. Some Foundation classes may seem designed for applications—NSUndoManager and NSUserDefaults, to name two—but they are included in Foundation because there can be uses for them that do not involve a user interface.
Foundation introduces several paradigms and policies to Cocoa programming to ensure consistent behavior and expectations among the objects of a program in certain situations. These include:
Object ownership and object disposal. Instead of an automatic garbage-collection mechanism, Foundation institutes a policy of object ownership that specifies that objects are responsible for releasing other objects that they have created, copied, or explicitly retained. NSObject (class and protocol) defines methods for retaining and releasing objects. Autorelease pools (defined in the NSAutoreleasePool class) implement a delayed-release mechanism and enable Cocoa programs to have a consistent convention for returning objects for which the caller is not responsible. For more about issues related to object ownership and disposal, see Memory Management Programming Guide for Cocoa.
Mutable class variants. Many value and container classes in Foundation have a mutable variant of an immutable class, with the mutable class always being a subclass of the immutable one. If you need to dynamically change the encapsulated value or membership of such an object, you create an instance of the mutable class. Because it inherits from the immutable class, you can pass the mutable instance in methods that take the immutable type. For more on object mutability, see “Object Mutability”.
Class clusters. A class cluster is an abstract class and a set of private concrete subclasses for which the abstract class acts as an umbrella interface. Depending on the context (particularly the method you use to create an object), an instance of the appropriate optimized class is returned to you. NSString and NSMutableString, for example, act as brokers for instances of various private subclasses optimized for different kinds of storage needs. Over the years the set of concrete classes has changed several times without breaking applications. For more on class clusters, see “Class Clusters”.
Notifications. Notification is a major design pattern in Cocoa. It is based on a broadcast mechanism that allows objects (called observers) to be kept informed of what another object is doing or is encountering in the way of user or system events. The object originating the notification can be unaware of the existence or identity of the observers of the notification. There are several types of notifications: synchronous, asynchronous, and distributed. The Foundation notification mechanism is implemented by the NSNotification, NSNotificationCenter, NSNotificationQueue, and NSDistributedNotificationCenter classes. For more on notifications, see “Notifications”.
The Foundation class hierarchy is rooted in the NSObject class, which (along with the NSObject and NSCopying protocols) define basic object attributes and behavior. For further information on NSObject and basic object behavior, see “The Root Class”.
The remainder of the Foundation framework consists of several related groups of classes as well as a few individual classes. There are classes representing basic data types such as strings and byte arrays, collection classes for storing other objects, classes representing system information such as dates, and classes representing system entities such as ports, threads, and processes. The class hierarchy charts in Figure 1-6, Figure 1-7, and Figure 1-8 depict the logical groups these classes form as well as their inheritance relationships.
These diagrams logically group the classes of the Foundation framework in the following categories (with other associations pointed out):
Value objects. Value objects encapsulate data of various types, giving access to the data and offering various manipulations of it. Because they are objects, they (and their contained values) can be archived and distributed. NSData provides object-oriented storage for streams of bytes whereas NSValue and NSNumber provide object-oriented storage for arrays of simple scalar values. The NSDate, NSCalendarDate, NSTimeZone, NSCalendar, NSDateComponents, and NSLocale classes provide objects that represent times, dates, calendar, and locales. They offer methods for calculating date and time differences, for displaying dates and times in many formats, and for adjusting times and dates based on location in the world.
Strings. NSString is another type of value object that provides object-oriented storage for a null-terminated array of bytes in a particular encoding. It includes support for converting string encodings among UTF-16, UTF-8, MacRoman, and many other encodings. NSString also offers methods for searching, combining, and comparing strings and for manipulating file-system paths. You can use an NSScanner object to parse numbers and words from an NSString object. NSCharacterSet (shown as a collection class in the diagram) represents a set of characters that are used by various NSString and NSScanner methods.
Collections. Collections are objects that store and vend other (usually value) objects in a particular ordering scheme. NSArray uses zero-based indexing, NSDictionary uses key-value pairs, and NSSet provides unordered storage of objects (NSCountedSet “uniques” the collection). With an NSEnumerator object, you can access in sequence the elements of a collection. Collection objects are essential components of property lists and, like all objects, can be archived and distributed.
Operating-system services. Many Foundation classes facilitate access of various lower-level services of the operating system and, at the same time, insulate you from operating-system idiosyncrasies. For example, NSProcessInfo lets you query the environment in which an application runs and NSHost yields the names and addresses of host systems on a network. You can use an NSTimer object to send a message to another object at specific intervals, and NSRunLoop lets you manage the input sources of an application or other type of program. NSUserDefaults provides a programmatic interface to a system database of global (per-host) and per-user default values (preferences).
File system and URL. NSFileManager provides a consistent interface for file operations such as creating, renaming, deleting, and moving files. NSFileHandle permits file operations at a lower level (for example, seeking within a file). NSBundle finds resources stored in bundles and can dynamically load some of them (for example, nib files and code). You use NSURL and NSURLHandle to represent, access, and manage URL sources of data.
Interprocess communication. Most of the classes in this category represent various kinds of system ports, sockets, and name servers and are useful in implementing low-level IPC. NSPipe represents a BSD pipe, a unidirectional communications channel between processes.
Threading and subtask. NSThread lets you create multithreaded programs, while various lock classes offer mechanisms for controlling access to process resources by competing threads. With NSTask, your program can fork off a child process to perform work and monitor its progress.
Notifications. See the summary of the notification classes in “Foundation Paradigms and Policies”.
Archiving and serialization. The classes in this category make object distribution and persistence possible. NSCoder and its subclasses, along with the NSCoding protocol, represent the data an object contains in an architecture-independent way by allowing class information to be stored along with the data.
Expressions and predicates . The predicate classes—NSPredicate, NSCompoundPredicate, and NSComparisonPredicate—encapsulate the logical conditions to constrain a fetch or filter object. NSExpression objects represent expressions in a predicate.
Spotlight queries . The NSMetadataItem, NSMetadataQuery and related query classes encapsulate file-system metadata and make it possible to query that metadata.
Objective-C language services. NSException and NSAssertionHandler provide an object-oriented way of making assertions and handling exceptions in code. An NSInvocation object is a static representation of an Objective-C message that your program can store and later use to invoke a message in another object; it is used by the undo manager (NSUndoManager) and by the Distributed Objects system. An NSMethodSignature object records the type information of a method and is used in message forwarding. NSClassDescription is an abstract class for defining and querying the relationships and properties of a class.
Scripting. The classes in this category help to make your program responsive to AppleScript scripts and Apple event commands.
Distributed objects. You use the distributed object classes for communication between processes on the same computer or on different computers on a network. Two of these classes, NSDistantObject and NSProtocolChecker, have a root class (NSProxy) different from the root class of the rest of Cocoa.
Networking. The NSNetService and NSNetServiceBrowser classes support the zero-configuration networking architecture called Bonjour. Bonjour is a powerful system for publishing and browsing for services on an IP network.
The Application Kit is a framework containing all the objects you need to implement your graphical, event-driven user interface: windows, dialogs, buttons, menus, scrollers, text fields—the list goes on. The Application Kit handles all the details for you as it efficiently draws on the screen, communicates with hardware devices and screen buffers, clears areas of the screen before drawing, and clips views. The number of classes in the Application Kit may seem daunting at first. However, most Application Kit classes are support classes that you use indirectly. You also have the choice at which level you use the Application Kit:
Use Interface Builder to create connections from user-interface objects to your application’s controller objects, which manage the user interface and coordinate the flow of data between the user interface and internal data structures. For this, you might use off-the-shelf controller objects (for Cocoa bindings) or you may need to implement one or more custom controller classes—particularly the action and delegate methods of those classes. For example, you would need to implement a method that is invoked when the user chooses a menu item (unless it has a default implementation that is acceptable).
Control the user interface programmatically, which requires more familiarity with Application Kit classes and protocols. For example, allowing the user to drag an icon from one window to another requires some programming and familiarity with the NSDragging... protocols.
Implement your own objects by subclassing NSView or other classes. When subclassing NSView, you write your own drawing methods using graphics functions. Subclassing requires a deeper understanding of how the Application Kit works.
The Application Kit consists of more than 125 classes and protocols. All classes ultimately inherit from the Foundation framework’s NSObject class. The diagrams in Figure 1-9 and Figure 1-10 show the inheritance relationships of the Application Kit classes.
As you can see, the hierarchy tree of the Application Kit is broad but fairly shallow; the classes deepest in the hierarchy are a mere five superclasses away from the root class and most classes are much closer than that. Some of the major branches in this hierarchy tree are particularly interesting.
At the root of the largest branch in the Application Kit is the NSResponder class. This class defines the responder chain, an ordered list of objects that respond to user events. When the user clicks the mouse button or presses a key, an event is generated and passed up the responder chain in search of an object that can respond to it. Any object that handles events must inherit from the NSResponder class. The core Application Kit classes—NSApplication, NSWindow, and NSView—inherit from NSResponder. You can find out more about these responder classes by reading “The Core Application Architecture”.
The second largest branch of classes in the Application Kit descend from NSCell. The noteworthy thing about this group of classes is that they roughly mirror the classes that inherit from NSControl, which inherits from NSView. For its user-interface objects that respond to user actions, the Application Kit uses an architecture that divides the labor between control objects and cell objects. The NSControl and NSCell classes, and their subclasses, define a common set of user-interface objects such as buttons, sliders, and browsers that the user can manipulate graphically to control some aspect of your application. Most control objects are associated with one or more cell objects that implement the details of drawing and handling events. For example, a button comprises both an NSButton object and an NSButtonCell object. See “Control and Cell Architecture” for further information
Controls and cells implement a mechanism that is based on an important design pattern of the Application Kit:. the target-action mechanism. A cell can hold information that identifies the message that should be sent to a particular object when the user clicks (or otherwise acts upon) the cell. When a user manipulates a control (by, for example, clicking the mouse pointer over it), the control extracts the required information from its cell and sends an action message to the target object. Target-action allows you to give meaning to a user action by specifying what the target object and invoked method should be. You typically use Interface Builder to set these targets and actions by Control-dragging from the control object to your application or other object. You can also set targets and actions programmatically.
Another important design-pattern based mechanism of the Application Kit is delegation. Many objects in a user interface, such as text fields and table views, define a delegate. A delegate is an object that acts on behalf of, or in coordination with, the delegating object. It is thus able to impart application-specific logic to the operation of the user interface. For more on delegation, target–action, and other paradigms and mechanisms of the Application Kit, see “Communicating With Objects”. For a discussion of the design patterns on which these paradigms and mechanisms are based, see “Cocoa Design Patterns”.
The following sections briefly describe some of the capabilities and architectural aspects of the Application Kit and its classes and protocols. It groups classes according to the class hierarchy diagrams shown in Figure 1-9 and Figure 1-10.
For the overall functioning of a user interface, the Application Kit provides the following classes:
The global application object. Every application uses a singleton instance of NSApplication to control the main event loop, keep track of the application’s windows and menus, distribute events to the appropriate objects (that is, itself or one of its windows), set up top-level autorelease pools, and receive notification of application-level events. An NSApplication object has a delegate (an object that you assign) that is notified when the application starts or terminates, is hidden or activated, should open a file selected by the user, and so forth. By setting the NSApplication object’s delegate and implementing the delegate methods, you customize the behavior of your application without having to subclass NSApplication. “The Core Application Architecture” discusses this singleton application object in detail.
Windows and views. The window and view classes, NSWindow and NSView, also inherit from NSResponder, and so are designed to respond to user actions. An NSApplication object maintains a list of NSWindow objects—one for each window belonging to the application—and each NSWindow object maintains a hierarchy of NSView objects. The view hierarchy is used for drawing and handling events within a window. An NSWindow object handles window-level events, distributes other events to its views, and provides a drawing area for its views. An NSWindow object also has a delegate allowing you to customize its behavior.
NSView is the superclass for all objects displayed in a window. All subclasses implement a drawing method using graphics functions; drawRect: is the primary method you override when creating a new NSView.
“The Core Application Architecture” describes NSView and NSWindow objects.
Controller classes for Cocoa bindings . The abstract NSController class and its concrete subclasses NSObjectController, NSArrayController, and NSTreeController are part of the implementation of Cocoa bindings. This technology automatically synchronizes the application data stored in objects and the presentation of that data in a user interface. See “The Model-View-Controller Design Pattern” for a description of these types of controller objects.
Panels (dialogs). The NSPanel class is a subclass of NSWindow that you use to display transient, global, or pressing information. For example, you would use an instance of NSPanel, rather than an instance of NSWindow, to display error messages or to query the user for a response to remarkable or unusual circumstances. The Application Kit implements some common dialogs for you such as the Save, Open and Print dialogs, used to save, open, and print documents. Using these dialogs gives the user a consistent look and feel across applications for common operations.
Menus and cursors. The NSMenu, NSMenuItem, and NSCursor classes define the look and behavior of the menus and cursors that your application displays to the user.
Grouping and scrolling views. The NSBox, NSScrollView, and NSSplitView classes provide graphic “accessories” to other view objects or collections of views in windows. With the NSBox class, you can group elements in windows and draw a border around the entire group. The NSSplitView class lets you append views vertically or horizontally, apportioning to each view some amount of a common territory; a sliding control bar lets the user redistribute the territory among views. The NSScrollView class and its helper class, NSClipView, provide a scrolling mechanism as well as the graphic objects that let the user initiate and control a scroll. The NSRulerView class allows you to add a ruler and markers to a scroll view.
Table views and outline views. The NSTableView class displays data in rows and columns. NSTableView is ideal for, but not limited to, displaying database records, where rows correspond to each record and columns contain record attributes. The user can edit individual cells and rearrange the columns. You control the behavior and content of an NSTableView object by setting its delegate and data source objects. Outline views (instances of NSOutlineView, a subclass of NSTableView) offer another approach to displaying tabular data. With the NSBrowser class you can create an object with which users can display and navigate hierarchical data.
The NSTextField class implements a simple editable text-input field, and the NSTextView class provides more comprehensive editing features for larger text bodies.
NSTextView, a subclass of the abstract NSText class, defines the interface to the extended text system. NSTextView supports rich text, attachments (graphics, file, and other), input management and key binding, and marked text attributes. NSTextView works with the Fonts window and Font menu, rulers and paragraph styles, the Services facility, and the pasteboard (Clipboard). NSTextView also allows customizing through delegation and notifications—you rarely need to subclass NSTextView. You rarely create instances of NSTextView programmatically either, since objects on Interface Builder’s palettes, such as NSTextField, NSForm, and NSScrollView, already contain NSTextView objects.
It is also possible to do more powerful and more creative text manipulation (such as displaying text in a circle) using NSTextStorage, NSLayoutManager, NSTextContainer, and related classes. The Cocoa text system also supports lists, tables, and non-contiguous selections.
The NSFont and NSFontManager classes encapsulate and manage font families, sizes, and variations. The NSFont class defines a single object for each distinct font; for efficiency, these objects, which can represent a lot of data, are shared by all the objects in your application. The NSFontPanel class defines the Fonts window that’s presented to the user.
The classes NSImage and NSImageRep encapsulate graphics data, allowing you to easily and efficiently access images stored in files on the disk and displayed on the screen. NSImageRep subclasses each know how to draw an image from a particular kind of source data. The NSImage class provides multiple representations of the same image, and also provides behaviors such as caching. The imaging and drawing capabilities of Cocoa are integrated with the Core Image framework.
Color is supported by the classes NSColor, NSColorSpace, NSColorPanel, NSColorList, NSColorPicker, and NSColorWell. NSColor and NSColorSpace support a rich set of color formats and representations, including custom ones. The other classes are mostly interface classes: They define and present panels and views that allow the user to select and apply colors. For example, the user can drag colors from the Color window to any color well. The NSColorPicking protocol lets you extend the standard Color window.
The NSGraphicsContext, NSBezierPath, and NSAffineTransform classes help you with vector drawing and support graphical transformations such as scaling, rotation, and translation.
The NSPrinter, NSPrintPanel, NSPageLayout, and NSPrintInfo classes work together to provide the means for printing and faxing the information that your application displays in its windows and views. You can also create a PDF representation of an NSView.
Use the NSFileWrapper class to create objects that correspond to files or directories on disk. NSFileWrapper holds the contents of the file in memory so that it can be displayed, changed, or transmitted to another application. It also provides an icon for dragging the file or representing it as an attachment. Or use the NSFileManager class in the Foundation framework to access and enumerate file and directory contents. The NSOpenPanel and NSSavePanel classes also provide a convenient and familiar user interface to the file system.
The NSDocumentController, NSDocument, and NSWindowController classes define an architecture for creating document-based applications. (The NSWindowController class is shown in the User Interface group of classes in the class hierarchy charts). Such applications can generate identically contained but uniquely composed sets of data that can be stored in files. They have built-in or easily acquired capabilities for saving, opening, reverting, closing, and managing these documents.
If an application is to be used in more than one part of the world, its resources may need to be customized, or localized, for language, country, or cultural region. For example, an application may need to have separate Japanese, English, French, and German versions of character strings, icons, nib files, or context help. Resource files specific to a particular language are grouped together in a subdirectory of the bundle directory (the directories with the .lproj extension). Usually you set up localization resource files using Interface Builder. See “Nib Files and Other Application Resources” for more information on the Cocoa internationalization facilities.
The NSInputServer and NSInputManager classes, along with the NSTextInput protocol, give your application access to the text input management system. This system interprets keystrokes generated by various international keyboards and delivers the appropriate text characters or Control-key events to text view objects. (Typically the text classes deal with these classes and you won’t have to.)
The following Application Kit classes provide operating-system support to your application:
Sharing data with other applications. The NSPasteboard class defines the pasteboard, a repository for data that’s copied from your application, making this data available to any application that cares to use it. NSPasteboard implements the familiar cut-copy-paste operation. The NSServicesRequest protocol uses the pasteboard to communicate data that’s passed between applications by a registered service. (The pasteboard is implemented as the Clipboard in the user interface.)
Dragging. With very little programming on your part, custom view objects can be dragged and dropped anywhere. Objects become part of this dragging mechanism by conforming to NSDragging... protocols; draggable objects conform to the NSDraggingSource protocol, and destination objects (receivers of a drop) conform to the NSDraggingDestination protocol. The Application Kit hides all the details of tracking the cursor and displaying the dragged image.
Spell checking. The NSSpellServer class lets you define a spell-checking service and provide it as a service to other applications. To connect your application to a spell-checking service, you use the NSSpellChecker class. The NSIgnoreMisspelledWords and NSChangeSpelling protocols support the spell-checking mechanism.
The abstract NSNibConnector class and its two concrete subclasses, NSNibControlConnector and NSNibOutletConnector, represent connections in Interface Builder. NSNibControlConnector manages an action connection in Interface Builder and NSNibOutletConnector manages an outlet connection.
As part of a standard Mac OS X installation, Apple includes (in addition to Foundation and Application Kit) several frameworks that vend Cocoa programmatic interfaces. (They may vend Carbon or other kinds of programmatic interfaces as well.) You can use these secondary frameworks to give your application capabilities that are desirable, if not essential. Some notable secondary frameworks include:
Core Data—The Core Data framework helps a program to manage graphs of model objects through their life cycles, including the persistent storage of their data in relational databases or flat files. It includes features such as undo and redo management, automatic validation of values, change propagation, and integration with Cocoa bindings. See “Other Cocoa Architectures” and Core Data Programming Guide for more information.
Sync Services—Using Sync Services you can sync existing contacts, calendars and bookmarks schemas as well as your own application data. You can also extend existing schemas. See Sync Services Programming Guide for more information.
Address Book—This framework implements a centralized database for contact and other personal information. Applications that use the Address Book framework can share this contact information with other applications, including Apple’s Mail and iChat. See Address Book Programming Guide for more information.
Preference Panes—With this framework you can create plug-ins that your application can dynamically load to obtain a user interface for recording user preferences, either for the application itself or system-wide. See Preference Panes for more information.
Screen Saver—The Screen Saver framework helps you create Screen Effects modules, which can be loaded and run via System Preferences. See Screen Saver Framework Reference for more information.
Web Kit—The Web Kit framework provides a set of core classes to display web content in windows, and by default, implements features such as following links clicked by the user. See Web Kit Objective-C Programming Guide for more information.
| < Previous PageNext Page > |
© 2006 Apple Computer, Inc. All Rights Reserved. (Last updated: 2006-12-20)
|