GTCFAutoreleaseRegion is a supplement to Core Foundation's memory management scheme. The code is released under the MIT licence.
Last updated on December 15, 2007.
Download the Code (about 4KB; licence included in source files.)
For some reason, Apple decided to forego autoreleasing in Core Foundation. Now, with the upcoming garbage collection in Leopard, this may seem to be somewhat of a moot point. But if you're developing for Tiger or earlier, or if you just don't trust garbage collection in C (hi mom!) then you've probably been miffed once in a while when you've had to work with Core Foundation. See, without autorelease pools, the following Objective-C one-liner:
NSString *greeting =
[NSString stringWithFormat: NSLocalizedString
(@
"GREETING_%@",
nil), NSUsername
()];
Is equivalent to the more tedious Core Foundation block:
CFStringRef gFormat = CFCopyLocalizedString(CFSTR("GREETING_%@"), NULL);
CFStringRef uName = CSCopyUsername(FALSE);
CFStringRef cfGreeting = CFStringCreateWithFormat(NULL, NULL, gFormat, uName);
/* use cfGreeting */
if (cfGreeting)
CFRelease(cfGreeting);
if (uName)
CFRelease(uName);
if (gFormat)
CFRelease(gFormat);
I'm aware it seems like a petty complaint, but less typing is always good when programming is involved. The fewer keystrokes you make, the fewer errors and bugs you risk. So with that in mind, I present Autorelease Regions for Core Foundation.
You might notice that I don't call them autorelease pools.
This is because, in Cocoa, autorelease pools are objects and can be manipulated as such. In my implementation, there are no objects or values you can manipulate, so the name change reinforces the idea that this is a different beast. Also, because autorelease regions are coded in pure C (with POSIX-specific and Core Foundation-specific code), they are not interchangeable with autorelease pools. You can still use autorelease pools, of course. This implementation is thread-safe.
Here's a usage example, based on the previous examples. It's still not as terse as the Objective-C equivalent, but it is shorter and cares less about memory management of individual Core Foundation values. Note that the usefulness of autorelease regions becomes more apparent when you're working with a lot of Core Foundation values. Also note that you can safely pass NULL to GTCFAutorelease():
GTCFAutoreleaseEnterRegion();
{
CFStringRef gFormat = GTCFAutorelease(CFCopyLocalizedString(CFSTR("GREETING_%@"), NULL));
CFStringRef uName = GTCFAutorelease(CSCopyUsername(FALSE));
CFStringRef cfGreeting = GTCFAutorelease(CFStringCreateWithFormat(NULL, NULL, gFormat, uName));
/* use cfGreeting */
}
GTCFAutoreleaseExitRegion();
The functions GTCFAutoreleaseRegionIsPresent() and GTCFAutoreleaseInstallMissingRegionHandler() are included, which can aid you when you're mixing with code that might not know about autorelease regions.
The functions GTCFAutoreleaseGetRegionValueCount() and GTCFAutoreleaseCopyRegionValues() are also present, and may be useful for debugging.
This code also includes a few useful symbols: GTCFPrint(), GTCFPrintv(), GTCFPrintValue(), kGTCFIndexMin, and kGTCFIndexMax.