Cocoa Is My Girlfriend

Taglines are for Windows programmers

Archive for the 'Coding Practice' Category

Cocoa Tutorial: Wiring Undo Management Into Core Data

Undo support in Cocoa is fantastic but for those who have tried to mix it with Core Data know that it can be a bit frustrating. Generally, undo support can be ignored in most applications and it will “just work”. But when Core Data is added to the recipe then things get a bit confusing and more complicated.

Read more

No comments

Cocoa Tutorial: Don’t Be Lazy With NSDecimalNumber (Like Me)

NSDecimalNumber is Objective-C’s solution to numbers that need to be very precise. The documentation defines it as:

NSDecimalNumber, an immutable subclass of NSNumber, provides an object-oriented wrapper for doing base-10 arithmetic. An instance can represent any number that can be expressed as mantissa x 10^exponent where mantissa is a decimal integer up to 38 digits long, and exponent is an integer from –128 through 127.

NSDecimalNumber

If you are dealing with currency at all, then you should be using NSDecimalNumber. However, since it is immutable and definitely not a primitive then it is difficult to use right? Well — yes — a bit. But if you do not want to see your $9.50 item displayed as $9.49999994 or something then you are better off using NSDecimalNumber right from the beginning. Otherwise you are going to be converting to it later and that is a LOT more painful.

Read more

5 comments

Git and XCode: A git build number script

Git has been gaining in popularity with Cocoa developers as well as open source developers. As I work it into my development workflow, one item that was missing was the automatic injection of the build number into the application bundle.

There are a few scripts floating around that perform this trick for subversion, but git handles build numbers a bit differently and it appears that no one has bothered to publish one. As is known, subversion uses an incrementing integer for build numbers. This makes it very easy to determine which build number came first and makes it very useful for a non-public version number. Git, however, uses a hash for each build number which is not incrementing and therefore not very useful for determining version numbers. However, it is still very useful for pulling up a specific build when a crash report is received, etc.

Therefore, with the help of Matt Long’s perl-fu, I have updated Daniel Jalkut’s subversion perl script to work with git. Since the build numbers are not sequential, I would not recommend using them for Sparkle. Therefore, in my own build process for iWeb Buddy, I hand select the version number (for example 1.0.4) and then use the short hash from git as the CFBundleVersion number. Normally this number is displayed in parens after the primary build number but, at least in iWeb Buddy, I have removed it from the display entirely. Since it is no longer a sequential number it would only potentially confuse users and it displays in the crash reports anyway.

The updated script is as follows:

# Xcode auto-versioning script for Subversion by Axel Andersson
# Updated for git by Marcus S. Zarra and Matt Long
 
use strict;
 
# Get the current git commit hash and use it to set the CFBundleVersion value
my $REV = `/opt/local/bin/git show --abbrev-commit | grep "^commit"`;
my $INFO = "$ENV{BUILT_PRODUCTS_DIR}/$ENV{WRAPPER_NAME}/Contents/Info.plist";
 
my $version = $REV;
if( $version =~ /^commit\s+([^.]+)\.\.\.$/ )
{ 
	$version = $1;
}
else
{
	$version = undef;
}
die "$0: No Git revision found" unless $version;
 
open(FH, "$INFO") or die "$0: $INFO: $!";
my $info = join("", <FH>);
close(FH);
 
$info =~ s/([\t ]+<key>CFBundleVersion<\/key>\n[\t ]+<string>).*?(<\/string>)/$1$version$2/;
 
open(FH, ">$INFO") or die "$0: $INFO: $!";
print FH $info;
close(FH);

Since git is distributed, there is no need to be online to produce a build. The script will grab the current abbrev-commit hash and will inject it into the current build’s Info.plist file.

4 comments

Cocoa Tutorial: Using NSError to Great Effect

Error handling is rarely fun. I find myself often re-coding a method after I realize that I need to handle one error condition or another. Usually, error handling involves either try/catch or some return code strategy. Neither of those is pretty or easy to maintain. For Objective-C development, however, there is another option — NSError.
Read more

5 comments

Cocoa Tutorial: Fixing Memory Leaks With Instruments

Leaks IconAs I am getting toward what I think is the end of coding for an application I hope to release soon, the nitty gritty work of fixing leaks, optimizing code, and squashing bugs has become the majority of what I’m doing now. Gone is the fun part of the application development process where I was creating features and solving new problems. It is now drudgery and focusing requires diligence. I know that the rewards are worth it as these final steps are what give an application stability and make it shine, but getting through it can be nothing but toil. Fortunately with the developer tools that shipped with Leopard, Apple has made this work much easier to handle in a little application called Instruments.
Read more

9 comments

Cocoa Tutorial: awakeFromNib vs applicationDidFinishLaunching

When developing an application in Objective-C and using Cocoa, there is a lot of “magic” that happens in the background. As we get more comfortable with the language and the APIs, we begin to discover the source of that magic and understand not only WHY it works but HOW it works.

One of those areas is the initialization and callbacks from the nib files to my code. Normally, when I want a controller to do something after the NIB/XIB has loaded, I add the method -(void)awakeFromNib and know that I will receive a call when all of the connections into the NIB/XIB are complete. But on what object does this get called and how?

Read more

8 comments

Does Objective-C Perform Autoboxing on Primitives?

One of the things about Objective-C that I find extremely useful is the ability to resolve a method call at runtime. In addition this same functionality allows us to do some fairly creative things with callbacks, passing messages between threads, etc.

However there is a bit of a trick when it comes to passing primitives though some of these methods. For example, one method that I use quite frequently is performSelectorOnMainThread:withObject:waitUntilDone:. How exactly does one pass a BOOL or an int to this method?
Read more

12 comments

Cocoa Coding Practice: Old School vs New

Garbage Collection

This post is in response to a few queries that I have received regarding my last post showing an NSOperation example. One of the questions raised that I will focus on is my -(void)dealloc method in the NSOperation subclass. The questions boiled down to:

Why are you using releases at all. Garbage collection is the future!

and

You should be just doing [self setVar:nil] instead of that [var release], var = nil; crap.

Read more

6 comments

Watch the latest videos on YouTube.com