BIGpedia.com - Cocoa (software) - Encyclopedia and Dictionary Online
encyclopedia search

Cocoa (software)

Cocoa is Apple Computer's native object-oriented application programming environment for the Mac OS X operating system. It is one of five major programming environments available for Mac OS X; the others are Carbon, Classic, BSD, and Java. (Environments such as Perl and Python are considered minor environments because they are not generally used for full-fledged application programming).

Cocoa applications are typically developed using the development tools provided by Apple, specifically Xcode (formerly Project Builder ) and Interface Builder. However the Cocoa programming environment can be accessed using other tools, such as Perl, Python and PyObjC.

For end-users, Cocoa applications are considered to be those written using the Cocoa programming environment. Such applications usually have a distinctive feel, since the Cocoa programming environment automates many aspects of an application to comply with Apple's Human User Interface guidelines.

Contents

Cocoa history

Cocoa is derived from the NeXTSTEP and OPENSTEP programming environments developed by NeXT in the late 1980s. Apple acquired NeXT in December, 1996, and subsequently went to work on the Rhapsody operating system that was supposed to be the direct successor of OPENSTEP and use OPENSTEP technology proper, and have an emulation base for Mac OS applications, which was termed Blue Box. The OPENSTEP base of libraries and binary support was termed Yellow Box. Rhapsody evolved into Mac OS X, and the Yellow Box became Cocoa.

Much of the work that went into developing OPENSTEP was applied to the development of Mac OS X. Cocoa is the most visible part of that synergy. There are, however, some important fundamental differences. The most visible of which is that NeXTSTEP and OPENSTEP used Display PostScript for on-screen display of text and graphics, while Cocoa depends on Apple's Quartz (which uses PDF). Cocoa also has a level of internet support, including the NSURL and WebKit HTML classes, and others, while under OPENSTEP there was only rudimentary support for managed network connections through NSFileHandle classes and Berkeley sockets.

Prior to its current use, the "Cocoa" trademark was the name of an application that allowed children to create multimedia projects. It was originally known as KidSim , and is now licensed to a third party and marketed as Stagecast. The program was discontinued as part of the rationalizations following Steve Jobs' return to the company.

Memory management

One feature of the Cocoa environment that is certainly unusual, if not unique, is its facility for managing dynamically allocated memory. Cocoa's NSObject class, from which most classes, both vendor and user, are derived, implements a reference counting scheme for memory management. Objects derived from the NSObject root class respond to a retain and a release messages, and keeps a retain count, which can be queried by sending a retainCount message. A newly allocated object, created with alloc, has a retain count of one. Sending that object a retain message increments the retain count, while sending it a release message decrements the retain count. When an object's retain count reaches zero, it is deallocated and its memory is freed. (Deallocation is to Objective C objects as destruction is to C++ objects. The dealloc method is functionally equivalent to a C++ destructor.)

In addition to manual reference counting, application programmers may choose to make use of autorelease pools. Sending an object an autorelease message registers a future release message with that thread's global autorelease pool. When the autorelease pool is deallocated, it sends the corresponding release message for every registered autorelease. Autorelease pools are generally deallocated and re-created at the end of the program's event loop, guaranteeing program flow has passed out of the block where that object was autoreleased. This means the application has predicatable performance and memory collection is generally invisible to the user, whereas under most fully automated schemes the application will sometimes suddenly stop responding when the garbage collection system is started.

Cocoa gives the programmer the choice of whether to manually manage memory management of objects or not. Opinions on this are divided. Some say that Cocoa's memory management is superior because it allows the programmer to have precise control over when his objects are deallocated, but does not burden him with the necessity of doing so for every object a program allocates, nor incurs the performance penalty that usually goes with automatic garbage collection. Others say that the entire scheme is unnecessary, and that Java-style automatic garbage collection is superior, because it removes the possibility of programmer error in memory management.

A combination of the two features is also possible. Modern garbage collectors often include features to be started and stopped mid-task, allowing the application to control how much time will be taken up whenever the system is called. Combining such a system with AppKit's "do it in the event loop" appears to offer a best-of-both-worlds solution. Such a system was successfully implemented under GNUStep, GNU's open source analog of OpenStep.

Main frameworks

Cocoa consists primarily of two Objective-C object libraries called frameworks. Frameworks are a construct unique to the NeXTSTEP/OpenStep/Cocoa family of programming environments. They are functionally similar to shared libraries, a compiled object that can be dynamically loaded into a program's address space at run-time, but frameworks add associated resources, header files, and documentation. Cocoa also includes a powerful versioning system to prevent the sort of problems that occur under Microsoft Windows, DLL Hell.

  • Application Kit or AppKit is directly descended from the original NeXTSTEP Application Kit. It contains code with which programs can create and interact with graphical user interfaces. NSWindow and NSButton are examples of AppKit classes.
  • Foundation Kit, or more commonly simply Foundation, first appeared in OpenStep. Foundation is a generic object-oriented library providing string and value manipulation, containers and iteration, distributed computing, event handling , and other functions that are not directly tied to the graphical user interface. NSString, NSDictionary and NSURLHandle are examples of Foundation classes.

The "NS" prefix, used for all framework objects, comes from Cocoa's NeXTSTEP/OpenStep heritage, as does the .nib file extension used by the Interface Builder. The .nib suffix originally stood for NeXT Interface Builder, but conventional wisdom now holds that .nib doesn't stand for anything; it is now said to refer to the word nib, meaning the sharpened point of a quill or pen.

A key part of the Cocoa architecture is its comprehensive views model. This is organised along conventional lines for an application framework, but is based on the PDF drawing model provided by Quartz. This allows creation of custom drawing content using PostScript-like drawing commands, which also allow automatic printer support and so forth. Since the Cocoa framework manages all the clipping, scrolling, scaling and other chores of drawing graphics, the programmer is freed from implementing basic infrastructure and can concentrate only on the unique aspects of an application's content.

Model, View, Controller

After many years of trial and error, the Smalltalk teams at Xerox PARC eventually settled on a design philosophy that led to easy development and high code reuse. Known as Model-view-controller, or MVC, the concept breaks an application into three sets of interacting object classes. The Models represent templates for the types of data a program will manipulate. Models might include Person or Vehicle, or more common examples like text file. On the "other end" of the system are the Views, which are responsible for the graphical display of the application. Views include not only the obvious examples such as Window or TextField, but also the application and event system as a whole. That is, the View represents the entire running GUI.

In the middle, and vital to the concept, are the controllers. Controllers translate the "commands" coming from the GUI into operations on the Models that they are editing. The controllers are also responsible for translating data in the models into a format useful for the View to use. Controllers allow the data (models) or look-and-feel (view) to be changed dramatically with little or no changes to the other layers. For instance, modifying a text-file based database application to use a SQL database instead requires only the models to be changed; the view can remain entirely unchanged, while the controller is likely to need little or no changes.

It is this middle layer of controllers that is missing from most application frameworks. MacApp and Microsoft Foundation Classes, for instance, lack this layer. Invariably applications written in these systems "export" information about the data directly into the GUI, and vice versa. Changes to either often require extensive changes to the entire program. That is not to say that one cannot write an MVC application using these frameworks, and many do, but the difference is that you actively have to try hard to write a "bad" program in Cocoa.

In more recent versions of Cocoa, those shipping with OS X 10.3 and later, Apple has started to provide pre-rolled controller objects. For instance, one common type of controller mediates access between a preferences control panel (Options in Windows-ese) and the preferences file stored on disk. The name and location of this file is well defined, as are the actions carried out on them, the only differences are the exact data stored in the file. Apple now includes a controller object for this task, one that stores a list of the data elements in the file, and handles all the modifications to them. Developers need only decide what to put in the file, and then wire up the control panel GUI to call the pre-rolled methods in the controller, something that takes a few minutes at most.

To date the number of controller objects has remained fairly limited -- there's no generic "document controller" for instance. Still, considering this layer is often missing entirely, it is a welcome addition to the system.

Invocations and bindings

In most object oriented languages, calls to methods are represented physically by a pointer to the code in memory. Since languages, like C++, demand that the functions be known at compile time, this presents a problem when trying to build a GUI; commands issued by widgets such as buttons or menu items must call a function, but that function belongs to an unknown class -- the correct "responder" to a message changes as the user switches windows, for instance. Most systems have responded to this problem by having a layer of intermediate objects known as "commanders", which are in some ways similar to mini-controllers. Commanders are written for each possible GUI action, and know how to examine the application's state to decide what function to call on what object. For instance, a Cut commander would be able to decide what document the action should be applied to by looking at the list of open windows.

Under Objective-C calls are represented instead by an invocation, essentially a string describing the call to be made. When a call is made, the invocation is sent into the ObjC runtime, matched against a list of possible methods, and then called. Since the invocation is text data, this allows it to be saved to a file, transmitted over a network, or manipulated in other ways.

The Cocoa GUI builder, Interface Builder (IB), makes extensive use of this facility. Under Cocoa there are no Commander objects, instead the actual method call is stored, as an invocation, directly in the application's resource file. Following our example above, the Cut menu item itself would contain data saying "call the cut method on the controller". When the application is loaded from disk these strings are turned back into commander-like objects automatically, with no developer effort at all. This can dramatically simplify the process of writing an application's GUI.

The system also allows direct access to values in the controller objects to populate the GUI. For instance, a text field can be "bound" to an instance variable in the controller object for a view, that value will automatically appear in the text field, and changes to the field will automatically be copied back into the controller. Cocoa uses a fairly flexible system for finding the right method to call. For instance, if a field is bound to "something", when the field attempts to draw itself it will attempt to find a method called "getSomething", "something", and finally a variable called "something" as well. The ObjC runtime makes this series of calls essentially invisible and free.

Another recent addition to the Cocoa system is the idea of "bindings". Bindings are an expanded version of the original Cocoa value-lookup system, automating the process of moving changes between the GUI and data. Previously the developer had to write code in the controller to notice these changes, either by asking the model objects or seeing that the GUI had called one of the controller's data methods, and then move that change into the GUI or model respectively. This "glue code" often represented the vast majority of an application's code. Oddly the Cocoa system has always included a system for "noticing" such changes for the cost of a single method call. Once registered, changes to objects would automatically call the appropriate code for moving the data.

Under the latest versions of Cocoa this process has been completely automated. By attaching data to a GUI object via the "bindings" instead of the traditional "value", the system registers that value for watching when the application is started. From then on, any changes in the GUI are automatically reflected back onto the models, and likewise, changes to the model generate notifications which cause the GUI to update itself. Using bindings the amount of code, and storage, in the controller objects falls dramatically. Controllers are reduced to housekeeping tasks; setting up the state of the form when it is opened, and collecting model objects to start off the display.

Rich objects

One of the most striking features of Cocoa, aside from the development aspects themselves, are the powerful "base objects" the system supplies.

As an example, consider the NSString class in Foundation, and the NSText system that manipulates it in the GUI. Almost all application frameworks base their string class on a minor expansion of the language's own strings -- for instance, almost all system use the C++ "char array" as their basis for strings. This leads to excellent performance and easy re-use within C++ libraries, but it also severely constrains the amount of functionality the system has. For instance, char arrays are not able to handle Unicode strings and other common problems, which led developer teams to introduce new string classes into their systems, greatly confusing the API. In contrast, NSString is perhaps the most powerful string object you could imagine. It fully supports not only ASCII and Unicode, but practically any known encoding, supporting development with a huge library of manipulation commands. Oddly the only obvious missing feature of NSString is a regex package, yet here too Cocoa manages to overdeliver, as the ObjC system allows a regex package to be "grafted onto" the existing string class via the use of categories.

Perhaps even more impressive is the GUI's object used to display and edit strings, NSText and its associated objects. The collection of objects involved permit the same code to implement anything from a simple single line text entry field to a complete multi-page, multi-column text layout schema, with full professional typography features such as kerning, ligatures, running text around arbitrary shapes, rotation, and of course full unicode support and anti-aliased glyph rendering. Paragraph layout can be controlled automatically or by the user, using a built-in "ruler" object that can be attached to any view. Spell checking is automatic, using a single universal dictionary used by all applications that uses the "squiggly underlining" introduced by Microsoft. And, as with all Cocoa objects, unlimited Undo/Redo support is built in. Using only the built in features, one can write a text editor application in as few as 13 lines of code. With new controller objects this may fall to zero.

For contrast, consider MacApp's solution to the same problem. Strings were based on char arrays, thereby limiting it, effectively, to Roman-based languages (English really). The developers also didn't want to write their own editor for the GUI, so they instead wrote a thin layer over the existing TextEdit controls in the MacOS. This limits the view to a single paragraph style, 32k text maximum, and only the most basic manipulations. Everything else, including complexities like Undo, are left to the developer. Of course this sort of "thin" support is not really useful, so developers are often forced to use 3rd party products to fill in the missing features. Yet even the best of the text views for MacApp come nowhere close to the power of NSText. This is not a slight on MacApp by any means, almost all application frameworks use similar "built in" controls intended for display of small strings only -- the same is true of MFC for instance.

Generally Cocoa classes tend to be some of the richest and most powerful out-of-the-box objects available. Customization of the system takes place, as it does on all systems, but in a typical application the amount of code dedicated to "fixing" the base classes is likely to be a very small amount compared to other frameworks, such as MacApp. For instance, under MacApp the basic text editing control is based on TextEdit, a control built into the MacOS from the earliest days that even Apple states should not be used for any "real world" applications. Thus, if one were to write a word processor using MacApp, the entire text handling system has to be written from scratch (although there are commercial alternatives). The same contrasts can be found throughout the Cocoa system with few exceptions; the table, window, clipboard handling etc. are all "best of breed".

Even when extensions are needed, which is "always" in practical settings, Cocoa's use of Objective-C makes this a much easier task. ObjC includes the concept of "categories" which allow code to be added onto existing classes at runtime. Adding functionality to the text system, say for regex, can be accomplished in a category without any changes to the original classes in the framework, or even access to its source. All text handling in the application will now support the new functionality. Under more common frameworks this same task would require the programmer to make a new subclass supporting the additional features, and then change all instances of the text classes to this new class. This can be very difficult if the application is being build in a GUI-based editor, which often won't allow you to easily place your own objects into the system in place of the system-supplied ones.

Rapid application development

Readers familiar with rapid application development (RAD) systems, like Visual Basic or Borland Delphi, may be struck by some of the parallels between their systems and Cocoa. Both offer easy access to the data in the display's controls, allowing it to be manipulated directly in the code without having to write any sort of controllers to mediate. Indeed, one of the hallmarks of a RAD system is that they allow you to access the GUI state directly and very easily, and the data is generally "typeless" (Variant under VB), allowing the code to be rather simplified. Another common feature of RAD systems is a tight integration between the GUI editor and the code supporting it.

For instance, Microsoft Access allows the developer to lay out the GUI in the forms editor, connect the various controls to the database fields they represent, and then attach "event handlers" to controls to call code. That code can then be edited simply by clicking on a button, which opens the code editor and moves to the right spot, or alternately creates an empty block of code if it has not yet been written. The code page is the controller, and the database, accessed via the form itself, is the model. Commander objects, as in Cocoa, are being handled invisibly; at runtime the system will look in the attached code (controller) for a method with the name "theControlName_theEvent", for instance "MyButton_click".

The same application written in Cocoa is somewhat more complex. For one, the tight integration between the GUI editor and code from Visual Basic is simply not as well developed under XCode -- although, oddly, it was in earlier versions of the NeXT development system. Although the general procedure of attaching event handlers to the GUI controls is the same, the environment makes the process of moving from code to GUI more complex. Another difference is that Cocoa does not (yet) include a system for database access, but this is perhaps not too surprising: Access is a database front-end, it was designed with this purpose in mind. To create such a project in Cocoa, a controller object must be written to mediate access to the database and retreive records as the GUI requests them. The rest of the code is similar, bindings make the data flow to and from the GUI's form, and the controller object isolates all the code used by the form in question.

There are, however, some interesting points that need to be considered. For one, the Cocoa application is written entirely in complied C code, and generally runs much faster than the same program in Visual Basic. Most of the code is actually in the frameworks themselves, which are already loaded up by the operating system, meaning that the program is very small and loads very quickly. Another difference is the power of the objects used in the GUI, although for a forms processing application these features may not be needed.

But the true difference lies in the flexbility of the two systems. Note that the Access version has bound the data directly into the GUI at several levels; changes to the underlying data model in the database will often require the developer to re-write huge portions of the GUI. Under Cocoa, these changes are isolated in the model objects, which can be easily modified to make the change invisible -- it makes no difference to the GUI if the model uses a SQL database or a text file for storage, and the model can change between those two without the GUI ever knowing. This is where the MVC model makes systems more maintainable, changes, even radical ones, are isolated to well known locations.

Finally, it is important to note that the controller in this case is not simply a file full of code, but a full-blown object. This means that multiple forms can all share the same controller object -- both as a way to allow multiple windows (forms) to display different parts of the same data, or alternately, to allow a number of similar forms to place their shared code in a single place. Consider the task of making a "largely similar" form in VB, which would require the developer to cut and past the code between the two forms, or isolate that code into a "module" and re-write both forms to call the module. Under Cocoa the developer would simply point, in IB, both forms at the same controller.

It is also worth noting that Apple is aware of the difficulty in accessing databases. One of NeXT's major products was Enterprise Objects Framework (EOF), a library of code that provided pre-rolled models and controllers for database applications. Using EOF database applications were almost as easy to write as under dedicated RAD systems like Access, the main differences being the less-than-tight integration between the various parts of the development enviornment. EOF has since, largely, been adbandoned. In its place Apple is introducing Core Data, a new set of lighter-weight objects intended to work hand-in-hand with bindings. Currently the Core Data system intends to support XML and simple binary files, as well as SQLite databases. EOF's "high-end" database integration is not currently being addressed, although the Core Data system could be expanded in that direction in the future.

Cocoa fits an interesting niche in development. It provides objects and a programming model that allows "full blown" applications to be developed, like those using MacApp or MFC, but to do so for considerably less effort -- developers generally claim 1/10th to 1/100th the code, with greater difference for simpler apps -- that is, simpler apps are far easier to write under Cocoa. Complex apps are complex, and the amount of savings due to the powerful GUI system may represent only a small amount of the code in total.

At the same time Cocoa can almost claim to be a RAD as well. The model makes development and modification of existing systems much easier than traditional development platforms, although not quite as easy as under systems such as Visual Basic. The majority of the difference is due to the development enviornment, not the programming model, and it appears Apple is at least interested in closing the loop on database access through Core Data.

Implementations

The Cocoa frameworks are written in Objective-C, and hence Objective-C is presently the preferred language for the Cocoa applications. Java bindings for the Cocoa frameworks are also available, but do not appear to have seen much real-world use. AppleScript Studio , part of Apple's Xcode Tools makes it possible to write (less complex) Cocoa applications using AppleScript.

Third party bindings are also available for other languages:

A more extensive list of implementations is available.

External links



The contents of this article are licensed from Wikipedia.org under the GNU Free Documentation License.
How to see transparent copy

01-04-2007 01:21:04