TweetFollow Us on Twitter

OpenStep Programming Intro

Volume Number: 13 (1997)
Issue Number: 5
Column Tag: OPENSTEP

What's Inside OPENSTEP... Really?

by Dave Klingler

An Introduction

The next several pages will be an attempt to give you a complete overview of OPENSTEP's development system as it might pertain to Rhapsody. Of course, we can't quite cover everything, but hopefully when you're done reading you'll know a little bit about OPENSTEP's basic parts and why developing under OPENSTEP has brought a happy grin to the faces of so many lucky programmers. OPENSTEP isn't perfect, but it's a well-designed springboard for a Macintosh programming renaissance during the next few years.

The major elements of OPENSTEP are the Foundation Kit, Interface Builder, Display Postscript, and Objective-C. There are some important minor players as well: ProjectBuilder, Header Viewer, Librarian and pswrap. All of these elements are probably unfamiliar to you unless you've used NEXTSTEP or OPENSTEP before, so let's start by taking a quick run through the development process under OPENSTEP to see where the pieces fit. We'll then go back to take a closer look at the major players.

The Development Process

The development cycle under OPENSTEP is fast enough that it tends to leave you wondering what you skipped when you're finished. I'll outline my own development cycle here; you'll probably evolve your own techniques once you start programming under OPENSTEP.

I usually begin by designing classes. This process is similar in any modern language; I figure out what data my program will use and derive a rough list of the major classes involved. Optimizing for speed versus efficiency, or server storage versus local storage, maintainability or even communications bandwidth will influence the design of my class system.

Over a period of about my first two years working with Objective-C I noticed that my techniques for designing new objects changed radically and often. I attribute that to the seemingly subtle, but huge differences between designing for Objective-C and for conventional languages like C or Pascal or even quasi-oop languages like C++. I take heavy advantage of dynamic typing and dynamic binding, which are not available in most languages other than Smalltalk. Java is currently mostly statically typed as well, but JDK 1.1 has reflection, a clear sign that the language is evolving in the right direction.

Bizarrely enough, I've gotten to the point where I write almost all my overview documentation before I write most of the code. I'll write test code to make sure a concept's going to work if it's something radical, but for the most part the code's completely described before it's written. I'm finished when any competent Objective-C programmer could write my app from my docs.

The documentation process is made easier by the fact that every Objective-C class is comprised of an interface file and a class implementation file. The interface file is a fancy header file that contains all the class variables that might be needed by a programmer using the class, plus prototypes for class methods and functions. When I'm designing a new class, of necessity I have to decide how that class will interact with the outside world. Whatever's externally available goes in the interface file and, with a comparatively tiny amount of work, an explanation goes with it into the documentation. Now I've got my interface files and all the documentation someone would need to use any of the classes in my new app.

At this point I'll either hand it off to a group of programmers for them to complete or paste the method and function prototypes from the interface into a new file called the class implementation file and begin filling out the class. This is the file that will actually contain the code for the class, and if you want to sell your classes you can compile this file and sell the result along with the interface file and the documentation. No one gets your source code, but they do get an explanation of all the classes' externally available variables and methods. Their classes can interface with your classes without knowing what's inside them, and that, after all, is what object-oriented programming is all about.

Lots of people in the OPENSTEP world sell classes instead of applications. One of the first classes I bought was BenaTong's Serial class, so that I could save some work writing a telecommunications package.

Because I've got a list of method prototypes to implement, I can just work my way through the file coding each one. When I reach the last one the class will be finished and quite often it "just works" with little or no debugging.

After designing the classes, it's time to pull out ProjectBuilder. ProjectBuilder manages the process of building a new application, module or palette under OPENSTEP. I tell ProjectBuilder to create a new project, create a few icons for the program and data files and drop them into ProjectBuilder's various boxes, drop in the new classes and double-click the "nib" file that ProjectBuilder has created for me. "Nib" stands for NeXT InterfaceBuilder, and that file contains the elements of the interface for the program, arguably most of it. Using Interface Builder might be compared to using a graphical version of ResEdit, but InterfaceBuilder does much more.

Next I design the rest of the program. Keep in mind that most of the elements in the average program other than the ones you've just designed (and they're usually very few) are already running in the OPENSTEP OS. This means that you can use "live" versions of those objects when you design your program's user interface by just grabbing what you want off a palette. You can also put your new classes into their own palette and use them too.

InterfaceBuilder allows you to design a program and "run" it without actually ever compiling it, because the code for any objects you're using other than your own has already been compiled. That code is running or at least available in the operating system as a shared library. When you've finished "drawing" your program the way you want it to work, including the classes you can't see but must be integrated anyway, you select "test interface" from InterfaceBuilder's menu and InterfaceBuilder runs the program for you without classes that it doesn't have yet. It gives you a big Frankenstein-style switch that you can use to shut the program down if your experiment doesn't like to quit. If you don't like the user interface, you can play with it until it's easy to use or does exactly what you wanted. It's far more powerful than an ordinary interface design program because you effectively have a graphical window into the guts of your app.

To release my application in other countries I can design nibs in other languages. OPENSTEP has support for English, French, Spanish, Swedish, German and Japanese. Most of the time it's just a matter of changing the words on the menus. There are localization firms that specialize in taking an English nib file and using it to create other language-specific versions of the program. They'll send back the nib and you can drop it into ProjectBuilder. They'll also translate other messages that reside in your code if it's needed. In most cases your app will "just work" in any language your customer chooses to use.

When I finish with InterfaceBuilder (and I might reverse the process and play with InterfaceBuilder first because it's sometimes more productive) I tell ProjectBuilder to compile the app. I'll select "debug" first if the app is large or I'm trying something fancy. If I'm debugging, ProjectBuilder will build the app with all its nibs and then compile the new classes with debugging extensions. It'll then drop me into gdb (a debugger) with the app loaded, where it's up to me to debug. There are various other debugging tools available under OPENSTEP that allow me to examine the app's messaging, memory usage, optimization, etc. Quite often if I'm really bamboozled I'll tell gdb to show me all the messaging taking place between objects. It's something like watching your children begin to talk.

I haven't yet discussed Postscript wraps or the cool process of trying out your Postscript code in Yap.app (there's a server running in the os, so why not?) before it goes into your project. ProjectBuilder knows about wraps and various other resources too, so it's an extremely useful tool for managing the process of creating a large application. Let's take a look at wraps and Display Postscript in general.

Display Postscript

Display Postscript (DPS) did not exist when NeXT first got together with Adobe to design a common language for writing to the screen and the printer. The general idea was to achieve true WYSIWYG by using the same code to describe both, and so DPS was born. Steve Jobs waxed poetic about XWindows while describing why NeXT had chosen DPS over X11; he called X "brain damaged". It is true that like many groundbreaking efforts, X became a little outmoded, and DPS is an elegant system. DPS is, however, imperfect in the context of the new age of multimedia, so we'll probably see many additions to DPS over the next few years.

Depending on your program's performance needs, there are various methods available for adding Display Postscript to your programs. Note that most programs use very little DPS, and unless you're designing a drawing application you probably won't have to learn much. That said, playing with Postscript interactively can be somewhat addictive, like fooling with turtle graphics and Logo if you're old enough to remember. You may choose to spend more time with it than is absolutely necessary, and if you do, the principles are the same.

You may or may not know that Postscript is a stack-based client-server page description system. Your program is the client, and the server is effectively either the screen or the printer. In theory it would be nice to write code that worked on both screen and printer; in practice you can't rely on all printers being Level II Postscript-compatible, so you may have to rewrite small sections of your display code for safe printing if you want to use Level II features.

There are three basic methods for using Display Postscript: operator functions, wraps and user paths, in descending order of their execution times. Operator functions are simplest, and you'll use them when you want to make a quick call to the server for a single function. Here's an example of a common combination of commands in Postscript, a "moveto" command followed by a "lineto" command. They create what is known in Postscript as a "path, and they're followed by an instruction to "stroke" the path, or fill it with ink.

10 10 moveto
50 50 lineto
stroke

As mentioned, one of the really fun parts of OPENSTEP is getting into Yap (Yet Another Postscript processor) and playing with Postscript interactively. Some time ago I ported BattleZone to NEXTSTEP, and I threw the entire opening screen into Yap to test it. I then moved elements of it around until I was happy with the way the screen looked. It was so much fun it almost made up for the rest of the porting process.

You can include these instructions in your code by using PS operator functions. OPENSTEP has two PS library functions for every PS operator, one for drawing in a default context and one that allows you to specify the context. Here's the equivalent of what's above, using the PS operator functions in psops.h, which draw in a default context:

PSmoveto(10, 10);
PSlineto(50,50);
PSstroke;

Now you've seen the original Postscript and the way you can implement it using single operator functions. As you can see, it is easy to convert any Postscript calls into operator function calls and insert them into your program. The problem with doing that is that each one of these calls is a separate message to the server. If you're calling one function occasionally, you're sending one message to the server occasionally, which is as good as you're going to get. For more than one line of Postscript, however, you'd do better to package your Postscript into a "wrap".

A wrap packages your calls into a C function library that ProjectBuilder can be told to include at compile time. You'd write a text file with the following in it:

definepsPSWDefs()
/ML {% X1 Y1 X Y
   moveto
   lineto
} bind def
endps
 
defineps multiline(float data[x]; int x; int length) 
  data
  1 1 length ML for
endps

Drop this into ProjectBuilder, which will call a program called "pswrap", to turn the file into a friendly, eminently readable and efficient package that looks like this:

/* ./sym/c_gpr.c generated from c_gpr.psw
  by unix pswrap V1.009 Wed Apr 19 17:50:24 PDT 1989  */
#include <dpsclient/dpsfriends.h>
#include <string.h>
#line 1 "c_gpr.psw"
#line 10 "./sym/c_gpr.c"
void PSWDefs( void ) 
{
 typedef struct {
  unsigned char tokenType; 
  unsigned char topLevelCount;
  unsigned short nBytes;
  DPSBinObjGeneric obj0;
  DPSBinObjGeneric obj1;
  DPSBinObjGeneric obj2;
  DPSBinObjGeneric obj3;
  DPSBinObjGeneric obj4;
  DPSBinObjGeneric obj5;
  char obj6[2];
  } _dpsQ;
 static const _dpsQ _dpsF = {
  DPS_DEF_TOKENTYPE, 4, 54,
  {DPS_LITERAL|DPS_NAME, 0, 2, 48},/* ML */
  {DPS_EXEC|DPS_ARRAY, 0, 2, 32},
  {DPS_EXEC|DPS_NAME, 0, DPSSYSNAME, 14},    /* bind */
  {DPS_EXEC|DPS_NAME, 0, DPSSYSNAME, 51},    /* def */
  {DPS_EXEC|DPS_NAME, 0, DPSSYSNAME,107},    /* moveto */
  {DPS_EXEC|DPS_NAME, 0, DPSSYSNAME, 99},    /* lineto */
  {‘M','L'},
  }; /* _dpsQ */
 register DPSContext _dpsCurCtxt = DPSPrivCurrentContext();
 char pad[3];
 DPSBinObjSeqWrite(_dpsCurCtxt,(char *) &_dpsF,54);
 if (0) *pad = 0;/* quiets compiler warnings */
}
#line 7 "c_gpr.psw"
#line 43 "./sym/c_gpr.c"
void multiline(const float data[], int x, int length)
{
 typedef struct {

  unsigned char tokenType;
  unsigned char topLevelCount;
  unsigned short nBytes;
  DPSBinObjGeneric obj0;
  DPSBinObjGeneric obj1;
  DPSBinObjGeneric obj2;
  DPSBinObjGeneric obj3;
  DPSBinObjGeneric obj4;
  DPSBinObjGeneric obj5;
  } _dpsQ;
 typedef struct {
  char obj6[2];
  } _dpsQ1;
 static const _dpsQ _dpsStat = {
  DPS_DEF_TOKENTYPE, 6, 54,
  {DPS_LITERAL|DPS_ARRAY, 0, 0, 48}, /* param[var]: data */
  {DPS_LITERAL|DPS_INT, 0, 0, 1},
  {DPS_LITERAL|DPS_INT, 0, 0, 1},
  {DPS_LITERAL|DPS_INT, 0, 0, 0},  /* param: length */
  {DPS_EXEC|DPS_NAME, 0, 2, 48}, /* ML */
  {DPS_EXEC|DPS_NAME, 0, DPSSYSNAME, 72},    /* for */
  }; /* _dpsQ */
 static const _dpsQ1 _dpsF1 = {
  {‘M','L'},
  }; /* _dpsQ1 */
 _dpsQ _dpsF;  /* local copy */
 register DPSContext _dpsCurCtxt = DPSPrivCurrentContext();
 char pad[3];
 register DPSBinObjRec *_dpsP = (DPSBinObjRec *)&_dpsF.obj0;
 register int _dps_offset = 48;
 _dpsF = _dpsStat; /* assign automatic variable */
 _dpsP[0].length = x;
 _dpsP[3].val.integerVal = length;
 _dpsP[0].val.arrayVal = _dps_offset;
 _dps_offset += x * sizeof(DPSBinObjGeneric);
 _dpsP[4].val.stringVal = _dps_offset;
 _dps_offset += 2;
 _dpsF.nBytes = _dps_offset+4;
 DPSBinObjSeqWrite(_dpsCurCtxt,(char *) &_dpsF,52);
 DPSWriteTypedObjectArray(_dpsCurCtxt, 
 dps_tFloat, (char *)data, x);
 DPSWriteStringChars(_dpsCurCtxt,(char *) &_dpsF1,2);
 if (0) *pad = 0;  /* quiets compiler warnings */
}
#line 12 "c_gpr.psw"

As you can see, it's easier to work in Postscript and let ProjectBuilder or pswrap do the work for you. It's also not a good idea to look too often at the files that pswrap generates, because you'll begin losing sleep.

There's a third way to interact with the DPS server, and that's with user paths. A user path is a way of packaging up a bunch of Postscript and translating it beforehand for the server. You can go even further by telling the server to store it in a user dictionary. That way you can make one call to the server, perhaps to supply arguments, and you minimize your program's messaging overhead. The technique is available when you need it, but from experience I can tell you that it's easier to use wraps and then go back and optimize where necessary with user paths. User paths are sometimes not very easy to debug.

For the most part whenever you use Postscript, you'll be drawing in a "View" object, a part of the Application Kit that maintains its own state for Postscript operations. Let's go back for a look at InterfaceBuilder and the Appkit and see why InterfaceBuilder plays such a large part in OPENSTEP programming.

Interface Builder

On the surface InterfaceBuilder looks essentially just like any interface builder. What it's doing underneath is far more rich and, in the end, far more useful to the programmer. InterfaceBuilder allows you to assemble all of the elements of your program and test them, in some cases without even compiling the program. You do this by grabbing objects off a palette and placing them where you want them. You can use almost any object in the Application Kit, which is an extremely rich source of material, or you can also make up palettes of your own objects and drop them into InterfaceBuilder.

A side benefit of using InterfaceBuilder is that much of your program will automatically conform to the OPENSTEP user interface standards. InterfaceBuilder doesn't limit you to creating applications. You can create modules as well, for use in other apps. After you're done bringing in the various elements of your program, InterfaceBuilder allows you to define the relationships these elements will use to work together. When you're finished, you can test your application without compiling it from within InterfaceBuilder. If a program works in InterfaceBuilder, it usually works after it's been compiled. Sometimes you'll even find yourself writing programs that never even run outside of InterfaceBuilder.

There are three major parts of InterfaceBuilder other than the area in the middle of the screen where you assemble your apps. The first is the file window (Figure 1), where all the different parts of your app are kept, including the parts that have no visual interface. As you add pieces to your application you'll see icons for each instance appear in the file window. You can also instantiate your own objects as you write code for them and they will appear here.

Figure 1. The File Window contains all the pieces of an application.

The file window keeps track of sounds, images, and information about the different classes available to you as well. You can use the file window's class browser to browse through the classes for a particular class. The class browser will allow you to parse new classes into InterfaceBuilder for use with the other objects. You can also subclass existing classes in the file window, and InterfaceBuilder will write skeleton code for your new subclass, including any action methods or outlets (pointers to other objects) your subclass might have. You can add these action methods and outlets in the Inspector window. Inspector windows are one of the most important user interface innovations in OPENSTEP, and a number of MacOS and Windows programs have begun using them. Essentially an inspector gathers all the important information about an object in one place. InterfaceBuilder makes fundamental use of inspectors in a most artful manner.

Figure 2. An InterfaceBuilder Attributes inspector window.

Figure 2 shows an InterfaceBuilder Attributes inspector for a fictitious button in a fictitious application. It's what you'd see if you selected the button in the same manner as selecting a line in a drawing program. The Attributes inspector allows you to change the title of the button instance, the icon it displays, the sound it makes, what kind of button it is (momentary push, pushOn/pushOff, etc.), and various other attributes. You can either specify sounds or icons by typing their names into the inspector or you can drop them on to the button and they'll appear here. InterfaceBuilder's Inspector Window carries all the important information about an individual object.

In addition to attributes you'll see other common elements such as details on the object's connections to other objects (messages it might receive or send, and to or from whom), the object's size in various dimensions, or help attachments to an interface element. In short, the Inspector Window contains detail. Last but not least is the Palette Window. It's the most intuitive window to use, because you simply drag objects from the palette to the application window or panel in which they should reside. You can drag Window and Panel objects, too.

Figure 3. InterfaceBuilder's Pallette window.

When you've finished dragging, browsing, parsing, clicking and typing, it's time to finish your application by drawing connections between all the different objects. When you've finished, your objects will be able to send messages to one another, and you can test them by selecting "Test Interface" in the menu. When you're all finished, click "Save" and InterfaceBuilder will archive the objects for you in a nib file. The nib contains most of the information about a program, and as you can see, anything in the nib is machine non-specific. That's why apps written in OPENSTEP are easily delivered across processor architectures. InterfaceBuilder is very cool.

Objective-C, alias Objective-C++

Fear not Objective-C. Yes, it is another programming language. It will, however, give you a competitive advantage in development that you probably don't believe possible right now. It's also easy to learn, and before you mumble to yourself that you've heard that before, let's take a look.

Objective-C was designed by Brad Cox, Smalltalk guru and the author of "Object-Oriented Programming, An Evolutionary Approach", a seminal work in OOP circles. He chose to make Objective-C a mix between Smalltalk and C, attempting to keep the best features of both. Objective-C takes dynamic typing and dynamic binding from Smalltalk. Within a class, however, it preserves the conciseness and efficiency of C.

On the surface, there are basically three differences between Objective-C and C:

1. Objective-C has a type called "id" that functions as a pointer to a generic object.

2. id is the default return type, rather than an int.

3. Objective-C has a messaging syntax for calling a method within an object. It uses embedded arguments, and it looks like

[object method] 

Here's an example of a message to a hypothetical object called graphObject to plot a point at location (x,y,z) with color graphColor:

[graphObject plotXAt:x andYAt:y andZAt:z 
 withColor:graphColor];

The syntax may seem strange with the embedded arguments thrown in, but it's not all that confusing. The method could be prototyped as

- (void) plotXAt: (float) x 
     andYAt: (float) y 
     andZAt: (float) z 
    withColor: (float) color;

The idea is that the format is more conducive to designing readable code. You can give your methods sentence-like names like the one above. I've been able to return to code I haven't seen for over a year and begin where I left off. I have never found another programming language that allows an ease of overall maintainability that compares to that of Objective-C. Syntax, however, may make Objective-C maintainable, but that isn't what makes it powerful. What makes it powerful is its features, and my favorite features of Objective-C are dynamic typing and binding.

The utility of a generic pointer to an object is that it gives the programmer the ability to point to an object without knowing what it is beforehand. Objective-C has reflection and discovery, so I can point to an unknown object and ask it to describe itself and whether it knows how to do certain things.

By using id to point to the object rather than statically typing it at runtime as an object of class X (you can do that too), I'm telling my program not to worry about what the object is yet. The object will be bound at runtime, and permiting me to choose what object I want during the program's execution instead of being forced to predict it at the link stage. The object I bind with at runtime could be written years after the calling code, and the calling program wouldn't know the difference.

Dynamic binding, dynamic typing and object discovery and reflection allow me to utilize true polymorphism. I might have several different code libraries containing classes that all have the same names but do different things. I might have a method call in a class, for instance, that looks like

[storageObject insertRecord:record];

One application might call for the storage method to be a hashtable. Another application might be best suited with a stack. The same class could be used for both, without any rewriting, because my stack class and hashtable class understand the same methods. All of this flexibility might be hard to manage, except that Objective-C allows me to declare formal protocols for classes to obey. A class declaration in Objective-C looks like

 Object

The same class declaration with an instruction to the compiler to make sure that the class follows a formal protocol looks like

 Object < BlowsUpThings, CannotBeStopped >

Protocols are truly powerful because they allow the programmer to easily take advantage of extreme polymorphism. A class can send the same message to classes of entirely different inheritance subtrees, which leads us to inheritance and scope coherency.

Scope coherency is not an issue with Objective-C; it uses a single inheritance model. If it's necessary to inherit methods of a wildly disparate nature that don't fit into a single inheritance model easily (and my experience has been that this case is rare), I can group methods into Categories. Categories aren't only good for that purpose, however; they're an extremely powerful tool with many uses.

Using a category, I can add methods to a class without having its source code. Effectively, I can extend classes that are already running, and all subclasses of those classes will inherit the abilities you added transparently.

I can also group like methods in a very large class into various categories. That ability nets me incremental compilation, better locality of reference, configurability of classes for special needs, and a way to divide up a large class among multiple developers.

With OPENSTEP, NeXT brought many of the best features of C++ into Objective-C, renaming the language Objective-C++. The end result is an extremely powerful marriage, sort of like C++ with a clean syntax and much-improved maintainability.

Some members of the Java team originally worked for NeXT, and Java resembles Objective-C far more closely on a structural level than it does C++. If you've looked into Java, and liked it, you'll love Objective-C.

Foundation Kit

Development under NEXTSTEP has always basically been AppKit + Objective-C + DPS, which somehow magically added up to more than the sum of their parts. Over the years, though, there were many NEXTSTEP developers who argued that NEXTSTEP was somehow impure in a few ways. It lacked garbage collection. It had no string objects. It didn't support Unicode. Many of the problems we discussed were along the lines of the perennial "why should the user throw the disk away to eject it?" discussion in the Mac world.

With OPENSTEP, NeXT had a chance to redo some things in a better fashion. Unfortunately, they were still under time pressure, which meant that some of the changes weren't optimal solutions. Still, OPENSTEP makes some good improvements on an already elegant foundation. NEXTSTEP was the first step; OPENSTEP is the next step.

Foundation Kit brings some final polish to the OPENSTEP development environment. It brings some basic utility classes, like NSArray, NSThread, and NSException. It brings reference counting. It brings Unicode strings. It brings... complexity. It brings slowness and bulk. Such is the price of power and maturity.

Mac developers are already familiar with Unicode. Foundation Kit defines the following encodings supported by NSString classes:

Encoding: Purpose:

NSASCIIStringEncoding for strict 7-bit ASCII encoding within 8-bit chars

NSEUCStringEncoding for Japanese text

NSISOStringEncoding for ISO Latin 1

NSNEXTSTEPStringEncoding for 8-bit ASCII encoding with some extensions

NSNonLossyASCIIStringEncoding (undefined)

NSSymbolStringEncoding (undefined)

NSUnicodeStringEncoding standard Unicode encoding for string objects

NSUTFStringEncoding 8-bit Unicode for transmission by ASCII-based systems

If you produce software that must be localized, you'll have plenty of fun with these. There's an encoding for every purpose.

Support for Unicode is important, but what's arguably an even bigger addition with Foundation Kit is that it brings garbage collection and standardized exception handling.

NeXT's solution to garbage collection is reference counting - possibly not the most elegant solution they could have chosen, but it's robust and it works. Basically the Application object for each application keeps an autorelease pool for storing references to objects. When an object is allocated or copied from another object, it is given a reference count of 1. Every message from another object to retain an object increments the reference count; every message to "autorelease" the object decrements it. When the reference count reaches 0, the autorelease pool releases the object.

To understand a little bit better, imagine that you have an object called spy. The spy object has the ability to concoct fantastic schemes to take over the world.

So if another object, say, the Control object, messages spy with a message to concoct a new scheme:

   [spy concoctScheme];

then spy might do something like

- (void) concoctScheme
{
   [currentScheme autorelease];
   currentScheme = [ [ Scheme alloc ] init ];
   return;
}

The rule is that if you create an object, you are responsible for releasing it. By sending currentScheme an autorelease message before returning it, spy is declaring that currentScheme does not need to exist beyond the current scope. By the way, the above example also illustrates nesting of messages, which works in a similar way to nesting function calls.

What if the spy had already passed the currentScheme object to its trusted partner, dirtyCounterSpy, and then subsequently sent the autorelease message to currentScheme as above? Eventually the other object might message the old currentScheme, which has probably long since been auto-released, and the dirtyCounterSpy object would crash hard, taking Control and spy and all the other objects in the secret espionage program with it.

The way to solve that would be for dirtyCounterSpy to send the older currentScheme object a retain message. Sending a retain message increments the older currentScheme's reference count in the autorelease pool. That way when the spy object sends an "autorelease" message to currentScheme, the reference count drops only to 1 instead of 0. The dirtyCounterSpy object can now keep the currentScheme object even though the object has been released by the spy object, and, in fact, even if the spy object is destroyed the dirtyCounterSpy object can use "retain" to keep currentScheme.

I hope this dirty lesson in in the affairs of espionage has briefly illustrated reference counting, and perhaps in other, more exciting ways it's illustrated a little of the power of OPENSTEP. There's quite a bit more to Foundation Kit, mostly in the area of abstraction, that is somewhat beyond the scope of this article. You have what you need, however, to grab a copy of Rhapsody and create that killer app.

 
AAPL
$95.54
Apple Inc.
-0.06
MSFT
$42.82
Microsoft Corpora
-0.34
GOOG
$563.80
Google Inc.
-7.80

MacTech Search:
Community Search:

Software Updates via MacUpdate

Adobe Lightroom 5.6 - Import, develop, a...
Adobe Lightroom software helps you bring out the best in your photographs, whether you're perfecting one image, searching for ten, processing hundreds, or organizing thousands. Create incredible... Read more
OneNote 15.2 - Free digital notebook fro...
OneNote is your very own digital notebook. With OneNote, you can capture that flash of genius, that moment of inspiration, or that list of errands that’s too important to forget. Whether you’re at... Read more
iStat Menus 4.22 - Monitor your system r...
iStat Menus lets you monitor your system right from the menubar. Included are 8 menu extras that let you monitor every aspect of your system. Some features: CPU -- Monitor cpu usage. 7 display... Read more
Ember 1.8 - Versatile digital scrapbook....
Ember (formerly LittleSnapper) is your digital scrapbook of things that inspire you: websites, photos, apps or other things. Just drag in images that you want to keep, organize them into relevant... Read more
OmniPlan 2.3.6 - Robust project manageme...
With OmniPlan, you can create logical, manageable project plans with Gantt charts, schedules, summaries, milestones, and critical paths. Break down the tasks needed to make your project a success,... Read more
Command-C 1.1.1 - Clipboard sharing tool...
Command-C is a revolutionary app which makes easy to share your clipboard between iOS and OS X using your local WiFi network, even if the app is not currently opened. Copy anything (text, pictures,... Read more
Knock 1.1.7 - Unlock your Mac by knockin...
Knock is a faster, safer way to sign in. You keep your iPhone with you all the time. Now you can use it as a password. You never have to open the app -- just knock on your phone twice, even when it's... Read more
Mellel 3.3.6 - Powerful word processor w...
Mellel is the leading word processor for OS X and has been widely considered the industry standard since its inception. Mellel focuses on writers and scholars for technical writing and multilingual... Read more
LibreOffice 4.3.0.4 - Free Open Source o...
LibreOffice is an office suite (word processor, spreadsheet, presentations, drawing tool) compatible with other major office suites. The Document Foundation is coordinating development and... Read more
Freeway Pro 7.0 - Drag-and-drop Web desi...
Freeway Pro lets you build websites with speed and precision... without writing a line of code! With it's user-oriented drag-and-drop interface, Freeway Pro helps you piece together the website of... Read more

Latest Forum Discussions

See All

Mister Beam Review
Mister Beam Review By Jordan Minor on August 1st, 2014 Our Rating: :: ILLUMINATINGUniversal App - Designed for iPhone and iPad Mister Beam’s puzzles are great. But its platforming? Not so much.   | Read more »
Hook Some More Fun With MapHook’s New Up...
Hook Some More Fun With MapHook’s New Update Posted by Jessica Fisher on August 1st, 2014 [ permalink ] iPhone App - Designed for the iPhone, compatible with the iPad | Read more »
Angry Henry And The Escape From The Heli...
Angry Henry And The Escape From The Helicopter Lords: Part 17: The Re-Reckoning Review By Jordan Minor on August 1st, 2014 Our Rating: :: GET TO THE CHOPPERUniversal App - Designed for iPhone and iPad | Read more »
Dead Trigger 2 Slaughter Master Tourname...
Dead Trigger 2 Slaughter Master Tournament Set to Reward for Masterful Murdering Posted by Ellis Spice on August 1st, 2014 [ | Read more »
Soccer Physics Review
Soccer Physics Review By Andrew Fisher on August 1st, 2014 Our Rating: :: HE FLAILS, HE SCORES!!!Universal App - Designed for iPhone and iPad Soccer Physics is as entertaining as it is absurd.   | Read more »
Train Your Own Dragon in DreamWorks’ Fir...
Train Your Own Dragon in DreamWorks’ First Story App – Dreamworks Press: Dragons Posted by Jessica Fisher on August 1st, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Dream Revenant Review
Dream Revenant Review By Lee Hamlet on August 1st, 2014 Our Rating: :: WATCH OUT FOR BED BUGSUniversal App - Designed for iPhone and iPad Dream Revenant takes players on a journey through a man’s subconscious. And though it’s full... | Read more »
Dawn of the Immortals Review
Dawn of the Immortals Review By Jennifer Allen on July 31st, 2014 Our Rating: :: RESPECTABLE EXPLORATIONUniversal App - Designed for iPhone and iPad Dawn of the Immortals might not re-invent the wheel, but it does tweak it a little... | Read more »
80 Days Review
80 Days Review By Jennifer Allen on July 31st, 2014 Our Rating: :: EPIC ADVENTUREUniversal App - Designed for iPhone and iPad A fantastic and fascinating re-envisioning of the classic novel by Jules Verne, 80 Days is a delightful... | Read more »
Battleheart Legacy Guide
The world of Battleheart Legacy is fun and deep; full of wizards, warriors, and witches. Here are some tips and tactics to help you get the most enjoyment out of this great game. | Read more »

Price Scanner via MacPrices.net

13-inch MacBook Airs on sale for $100 off MSR...
B&H Photo has the new 2014 13″ MacBook Airs on sale $100 off MSRP. Shipping is free, and B&H charges NY sales tax only. They also include free copies of Parallels Desktop and LoJack for... Read more
16GB iPad Air on sale for $399, save $100
Best Buy is offering the 16GB WiFi iPad Air for $399.99 on their online store for a limited time. Their price is $100 off MSRP. Choose free shipping or free store pickup (if available). Price is for... Read more
All Over For Tablets Or Just A Maturing, Evol...
CNN’s David Goldman weighs in on tablet sector doom and gloom, asking rhetorically: “Is this the beginning of the end for the tablet?” Answering that, he contends that hysteria and panic are... Read more
Letterspace 1.0.1 – New Free iOS Text Editor...
Bangkok, Thailand based independent developer Sittipon Simasanti has released Letterspace, a new text editor for iPhone, iPad, and iPod touch devices. Letterspace is a note taking app with an... Read more
Save up to $130 on an iPad mini with Apple re...
The Apple Store has Certified Refurbished 2nd generation iPad minis with Retina Displays available for up to $130 off the cost of new models, starting at $339. Apple’s one-year warranty is included... Read more
iPad Cannibalization Threat “Overblown”
Seeking Alpha’s Kevin Greenhalgh observes that while many commentators think Apple’s forthcoming 5.5-inch panel iPhone 6 will cannibalize iPad sales, in his estimation, these concerns are being... Read more
Primate Labs Releases July 2014 MacBook Pro P...
Primate Labs’ John Poole has posted Geekbench 3 results for most of the new MacBook Pro models that Apple released on Tuesday. Poole observes that overall performance improvements for the new MacBook... Read more
Apple Re-Releases Bugfixed MacBook Air EFI Fi...
Apple has posted a bugfixed version EFI Firmware Update 2.9 a for MacBook Air (Mid 2011) models. The update addresses an issue where systems may take longer to wake from sleep than expected, and... Read more
Save $50 on the 2.5GHz Mac mini, plus free sh...
B&H Photo has the 2.5GHz Mac mini on sale for $549.99 including free shipping. That’s $50 off MSRP, and B&H will also include a free copy of Parallels Desktop software. NY sales tax only. Read more
Save up to $140 on an iPad Air with Apple ref...
Apple is offering Certified Refurbished iPad Airs for up to $140 off MSRP. Apple’s one-year warranty is included with each model, and shipping is free. Stock tends to come and go with some of these... Read more

Jobs Board

*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
Sr. Product Leader, *Apple* Store Apps - Ap...
**Job Summary** Imagine what you could do here. At Apple , great ideas have a way of becoming great products, services, and customer experiences very quickly. Bring Read more
Sr Software Lead Engineer, *Apple* Online S...
Sr Software Lead Engineer, Apple Online Store Publishing Systems Keywords: Company: Apple Job Code: E3PCAK8MgYYkw Location (City or ZIP): Santa Clara Status: Full Read more
Sr Software Lead Engineer, *Apple* Online S...
Sr Software Lead Engineer, Apple Online Store Publishing Systems Keywords: Company: Apple Job Code: E3PCAK8MgYYkw Location (City or ZIP): Santa Clara Status: Full Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.