Archive for the 'Coding Practice' Category
My current Prefix.pch file
I have posted and discussed this file a few times but as with all things it has been touched, tweaked, and generally improved upon.
In this article we will discuss the latest iteration of my Prefix.pch file. As with anything I post, it is available for you to use as you see fit.
The File
For those who don’t want to read the entire post, here is the file:
1 2 3 4 5 6 7 8 9 10 11 12 | #ifdef DEBUG #define DLog(...) NSLog(@"%s %@", __PRETTY_FUNCTION__, [NSString stringWithFormat:__VA_ARGS__]) #define ALog(...) [[NSAssertionHandler currentHandler] handleFailureInFunction:[NSString stringWithCString:__PRETTY_FUNCTION__ encoding:NSUTF8StringEncoding] file:[NSString stringWithCString:__FILE__ encoding:NSUTF8StringEncoding] lineNumber:__LINE__ description:__VA_ARGS__] #else #define DLog(...) do { } while (0) #ifndef NS_BLOCK_ASSERTIONS #define NS_BLOCK_ASSERTIONS #endif #define ALog(...) NSLog(@"%s %@", __PRETTY_FUNCTION__, [NSString stringWithFormat:__VA_ARGS__]) #endif #define ZAssert(condition, ...) do { if (!(condition)) { ALog(__VA_ARGS__); }} while(0) |
This does not replace the Prefix.pch that comes with your project but it does go at the top of every project that I work on. The rest of this post we will review what this does. Read more
11 commentsCreating a NSManagedObject that is Cross Platform
An interesting question came up on Stackoverflow today so I decided to expound upon it in a short blog post.
A situation that I believe we are going to be seeing more and more often is one where application developers are writing multiple “versions” of their applications to be used on the desktop, their iPhone and now the iPad.
Because of that situation, it is becoming even more important that we write as much portable code as possible. Fortunately, our model can be completely portable between the two platforms.
7 commentsCocoa Tutorial: Creating your very own framework
There are numerous situations where creating your own framework is advantageous. Perhaps you have a block of code that you use repeatedly in many different projects. Perhaps you are building a plug-in system for your application and want the infrastructure to be available both to the application and to any plugins that are coded.
A Cocoa framework is another project type in Xcode. The end result is a bundle, similar to an application bundle. Inside of this bundle is the compiled code you wrote and any headers that you want exposed. The headers are important. Without them, just like any other piece of Objective-C code, it is very hard to code against.
2 commentsVersion Control Makes You A Better Programmer
I’m a believer. I’ve used version control before, but Marcus has convinced me that with a little known version control system called Git, written by Linus Torvalds (the creator of Linux), version control is not just about versioning, it’s about expressing yourself with your code and collaborating with others, seamlessly.
As memory serves the only time I’ve used version control in a meaningful way the system I was using was Visual SourceSafe from Microsoft. I know. Blech! It’s awful! I’ve pulled code from many a CVS or Subversion repository, but I’ve never really used them in the way they are intended to be used. Now, thanks to Marcus, I realize that version control isn’t just about versioning any more. It’s a whole methodology/ideology that makes better programmers. Here is what I mean. Read more
12 commentsCoding Practice: Cleaning up the default Core Data project
In this entry I am going to do something a little different. Instead of showing some wicked code, I am going to reformat one of Apple’s default templates.
Apple writes some amazing code. Unfortunately a lot of their templates demonstrate simply terrible coding practices. What is worse, people take these templates and assume that they are the proper practice for coding in Objective-C and propagate that poor code into their own projects.
The first example I am going to tackle is the AppDelegate class that is auto generated in the Core Data template. This is not the Core Data Document template but the standard application template.
7 commentsCocoa 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.
8 commentsCocoa 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.
9 commentsGit 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.
7 commentsCocoa 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
7 commentsCocoa Tutorial: Fixing Memory Leaks With Instruments
As 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
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?
11 commentsDoes Objective-C Perform Autoboxing on Primitives?
This article is inaccurate.
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
14 commentsCocoa Coding Practice: Old School vs New
![]()
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.
6 comments
