DirectNET

Data Center Management Solutions including UPS Systems, Data Center Cooling, KVM over IP & IP Power Strips, Server Racks and Server Rack accessories; KVM Switches and KVM Extenders; Rackmount Monitors and Rackmount Keyboards.


NAVIGATION
Home
Store
INSIDE MAC
Television Shows
Broadcast Shows
Daily News Shows
Special Shows
EVENTS
DAILY TIPS
Design
Mac OS X
Mac OS X UNIX
COMMUNITY
Forums
Surveys
NEWS
Current
Press
Archive
FEATURES
Editorial
Dr. Mac
Reviews
Reader Reports
RESOURCES
FAQ
Documentation
Learning Center
MAN pages
Glossary
Tutorials
Tips
Links

OUR PARTNERS

Tutorials 

Cocoa For Amateurs - Project 1 - Project Outline, Starting the Project, and Intro to Memory Management

by Dr. John Timmer, Contributing Editor


What OutLauncher is going to do

We're going to start out slow, with a small application that doesn't have a GUI. Within this small application, however, we're going to sort out how to manage memory, introduce the concept of a run loop, execute code at specific intervals, and introduce working with files. As an added bonus, we'll even do a bit of integration with OS-X's Unix environment. Although the program we'll make is only helpful to a limited group of users, the techniques I'll be introducing here will be applicable to future projects.

The actual program we're writing will perform a relatively simple task, but variations on it may be more generally useful. The program will run in the background, periodically checking whether there are any users logged in. If there aren't, it will scan a folder for shell scripts and execute them. This can be useful for cleaning up after users, resetting a guest account, or running certain processes only when a user is logged out. Since this will be running in the background for the computer's entire uptime, it's going to be designed to run as a daemon launched as a startup item.

Starting the project

We're going to create a project that takes advantage of the Cocoa classes which are not designed for use with a GUI - the Foundation classes. Launch Project Builder and select "New Project" from the "File" menu. In the dialog that appears, scroll down to the bottom and select "Foundation Tool". Hit "Next", and name your project "OutLauncher", saving it wherever it's convenient. Project Builder will then create all the files we need to get started. It's worth taking a quick look over what's included:

The folder called "Source" simply contains all the code that currently exists in your project. At this point, the only thing of significance there is "main.m", which we'll get to later. The "Documentation" folder contains a man page template, which we're not going to bother using here, since this program will be a daemon rather than a standard tool. Since we've decided to make this a Foundation based tool, Project Builder has already linked the project with the Foundation Framework. You can also link against other Frameworks if you need them; we'll see how to do this in a future tutorial. Finally, you can see the Product folder, which contains the results of building your project. The red text here denotes that our product, OutLauncher, is a missing file - not surprising, since it hasn't been built yet. In more elaborate projects, the "Project" folder will allow you to examine the contents of the entire application bundle.

Memory Management

Now, let's look over the source of the "main.m" file:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

// insert code here...

NSLog(@"Hello, World!");

[pool release];
return 0;
}

As things stand, half the code (the Autorelease pool) is devoted to memory management, which means this is a good time to go over memory management in Obj-C. Stepwise has a couple of tutorials, and there is another at Cocoa Dev Central, but I'll also give a quick rundown here. Most objects we'll be creating are put by default into an autorelease pool. If we don't do anything else to keep them around, the memory they use gets freed up when the active autorelease pool is purged. In GUI applications, the application itself creates an autorelease pool that's recycled for you as part of the regular workings of the program's runloop (for more on runloops, see the next tutorial). In this way, most memory we use gets taken care of without any programmer intervention.

There are a couple of ways to keep objects around for longer. One is to create them using a method such as "alloc", which keeps the memory around by default. You can also do that explicitly with a "retain" message. These objects will be kept around even if you lose track of them in the program, so using them creates a danger of memory leaks. To get rid of them and keep them from leaking, you need to send those objects a "release" message. As soon as there are a number of release messages equal to the total of the alloc + retains, the object goes into the autorelease pool. Using too many release messages, however, will clear the memory too soon and cause errors, so you have to keep things balanced. For those situations where you need to keep an object around for a breif period (say, returning one from a method), you can also use the "autorelease" message. This will keep the object around a for long enough for some other code to decide whether to retain it or not, then drop it into the autorelease pool.

As I mentioned above, in GUI and other runloop-based applications, autorelease pool creation and destruction are handled for you. Since a tool like this may just execute briefly and then exit without entering into a runloop, autorelease pools need to be created explicitly. There are other cases where you may want to make your own autorelease pool - for example, when in a loop where you create many objects, you can cut down on total memory use by allocating and releasing pools explicitly.

Tommarow in the next section, I'll intentionally make some errors in memory management to give you a sense of how to detect problems and figure out where they occur.

If you have any questions or comments about this article, feel free to e-mail me at john_timmer@osxfaq.com

Copyright © 2000-2008 Inside Mac Media, Inc. All rights reserved.
Apple assumes no responsibility with regard to the selection, performance, or use of the products or services. All understandings, agreements, or warranties, if any, take place directly between the vendors and prospective users.
Apple, the Apple logo, Mac, PowerMac G4, PowerMac G5, Xserve, Xserve RAID, PowerBook, iBook, Airport, AirPort Extreme, iMac, eMac, iLife, iMovie, iCal, iPhoto, iTunes, QuickTime, FireWire, iPod, iSight, AppleWorks, Macintosh, Jaguar, Panther, Mac OS, Mac OS X and Mac OS X Server are trademarks of Apple Computer, Inc.