Quality Coding

Category Archives for iOS Project Structure & Language

Emoji: Postbox

Objective-C init: Why It’s Helpful to Avoid Messages to self

I sometimes talk to myself. Our classes often do. But there are a couple of places where doing so is risky in Objective-C: init and dealloc.

This post is part of the Code Smells in Objective-C series.

Here’s something I see a fair bit in code for Objective-C init and dealloc. I’ll give a simple example. Can you tell what’s wrong?

- (id)initWithFoo:(id)foo
    self = [super init];
    if (self)
       self.something = foo;
    return self;

- (void)dealloc
    self.something = nil;
    [super dealloc];

Hint: It’s those self-dots. They have a tendency to lull people into thinking they’re simple assignments. But remember, dot notation conceals messaging.

Let’s avoid dot notation and try again:

Continue reading

Emoji: Smiling Face With Horns

Is Dot Notation in Objective-C 100% Pure Evil?

Dot notation for messaging isn’t just an Objective-C code smell. It’s evil, I tell you!

Update: I recently changed my mind! See my post In Which I Embrace Dot Notation…

This post is part of the Code Smells in Objective-C series.

…OK, so that’s hyperbole. I do manage to coexist with dot notation in projects that have it. But I won’t write it myself. Here are 3 reasons I avoid dot notation in my code:

Continue reading

Emoji: Bandaged Face

4 Ways Precompiled Headers Cripple Your Code

When used well, a precompiled header can save you precious compilation time. But when used poorly, precompiled headers can hide problems in your source code that you may not notice until you try to reuse parts of it for another project.

This post is part of the Code Smells in Objective-C series.

Precompiled headers were invented for one purpose: to make compiling faster. Rather than parsing the same header files over and over, these files get parsed once, ahead of time. Speed is important! The faster you compile, the faster you can complete the feedback loop to see if recent changes were successful.

In Xcode, you do this by including the header files you want in a “prefix header,” and enabling “Precompile Prefix Header” so they get precompiled. But the idea behind a prefix header is different from precompiling. A prefix header is implicitly included at the start of every source file. For example, if your prefix header is Prefix.pch, it’s like each source file sneaks

#import "Prefix.pch"

at the top of the file, before anything else. This can be handy for project-wide #defines. (Just remember that in general, #defines are a code smell.)

It’s also handy for precompiled headers. The fact that every source file includes these precompiled headers is an artifact of being in the prefix header.

And this is where things start to go wrong…

Continue reading

Emoji: Female Detective

How to Debug iOS Version-Specific Bugs

Here’s the scenario: A bug is reported. But the bug occurs only on the latest version of iOS. On earlier versions, everything’s a-okay. Ack!

Has this happened to you? I’ve dealt with it a couple of times. You can stare at the code as hard as you want, and come up with various theories. But you won’t get far that way. Why? Because on that earlier iOS, everything works. You won’t find any glaring errors just by looking.

So how do you debug iOS-specific problems? What you need is a diagnostic tool. Over on the iPhone Application Development blog, I describe a method that’s helped me crack tough problems. See iOS Version-Specific Bug!

Question: How have you dealt with version-specific bugs? Leave a comment below.

Emoji: Factory

Objective-C Factory Methods: How to Do Them Wrong (and Right)

We all use factory methods, a.k.a. convenience methods. We often write them ourselves. But there’s a wrong way, and a right way, to write a factory method for your Objective-C class. Do it wrong, and you cut off some features of Objective-C. Do it right, and you open yourself up to new object-oriented possibilities.

Let’s back up and review what we mean by a factory method. This is a convenience method that you invoke on a class to say, “Make me one of your kind.” (Some folks call this a “convenience constructor” which is odd to me, because the underlying mechanics are quite different from Java or C++.)

Continue reading

Emoji: Ballot Box with Check

How I Switch between Staging and Production URLs

How do you switch your app between a staging URL (for development and testing) and a production URL (for real world use)? I’ve changed my mind about my approach, because one size doesn’t fit all.

In 9 Code Smells of Xcode Preprocessor Macros, I originally suggested that instead of using the preprocessor, it would be better to use a plist. Here’s the preprocessor code smell:

static NSString *const fooServiceURL = @"https://dev.foo.com/services/fooservice";
static NSString *const fooServiceURL = @"https://foo.com/services/fooservice";

I wrote, “Instead of defining these URLs in your code, treat them as resource definitions and place them in a plist, organized by type.”

Continue reading

Emoji: Lion

Wild #imports: How to Tame File Dependencies

Like all C-based languages, Objective-C files usually come in pairs: there’s a header file, and an implementation file. Either can use the #import directive to include other header files. And if you’re not careful, it’s easy to create an explosion of file dependencies. What are the consequences? How do we tame #import dependencies?

[This post is part of the Code Smells in Objective-C series.]

Continue reading

Emoji: Classical Building

Objective-C Is Still C (Not Java!)

October 2011 saw the passing of giants:

  • Steve Jobs. You work with his toys everyday.
  • Dennis Ritchie, inventor of the C programming language, co-inventor of Unix. You work with his stuff everyday (but we forget that).
  • John McCarthy, inventor of Lisp. We use the descendants of his invention every day (without realizing it).

By his vested Interweb powers, Tim O’Reilly has declared that October 30 be Dennis Ritchie Day. In his honor, I wanted to write something that’s been bothering me about the way people are learning Objective-C:

Continue reading

Emoji: Cheese

9 Ways You Can Avoid ObjC Xcode Preprocessor Macros

With few exceptions, using Xcode preprocessor macros is a code smell. C++ programmers have had this beat into them: “Don’t use the preprocessor to do something the language itself provides.” Unfortunately, more than a few Objective-C programmers have yet to get that message.

This post is part of the Code Smells in Objective-C series.

Here’s a handy command to run from Terminal. It examines source files from the current directory down, showing preprocessor macros use that you should double-check.

find . \( \( -name "*.[chm]" -o -name "*.mm" \) -o -name "*.cpp" \) -print0 | xargs -0 egrep -n '^\w*\#' | egrep -v '(import|pragma|else|endif)'

This command builds in some exceptions. For example, #import directives are vital. #pragma mark can be useful. …But I want to question pretty much everything else! Why does it matter? Because every time you use the preprocessor, what you see isn’t what you compile. And for #define macros used as constants, there are certain pitfalls to avoid — when we could just avoid them altogether.

Here are some common Xcode preprocessor macros, and how to replace them:

  1. #include
  2. Macros
  3. Constants: Numeric constants
  4. Constants: Ascending integer constants
  5. Constants: String constants
  6. Conditional compilation: Commenting out code
  7. Conditional compilation: Switching between experiments
  8. Conditional compilation: Switching between staging and production URLs
  9. Conditional compilation: Supporting multiple projects or platforms

Continue reading

Emoji: Baby

Code Smells in Objective-C

Code smells. I’ve mentioned “code smells” at work, only to discover that my coworkers didn’t know what I meant. It’s basically a diaper-changing metaphor: “If it stinks, change it.”

A code smell isn’t “awful code that makes you hold your nose.” Rather, it’s a simple indication that something may need to be changed. Quite often, you won’t notice a code smell until someone else describes it. This is what Kent Beck and Martin Fowler did in the Refactoring book: created a list of smells, and what to do about them.

Continue reading