Wednesday, November 30, 2011

Read/Write Lockless Exclusion

With the recent release of iOS 5, GCD now has a simple and elegant solution to the reader writer problem that utilizes lockless exclusion. In summary, this involves using dispatch_async (or dispatch_sync) to enqueue "reader" blocks onto a user concurrent queue. These blocks may be used to read some kind of data but not write to it. If we need write access, then we can use the new dispatch_barrier_async (or dispatch_barrier_sync) function. This will put a special barrier block on the queue. The blocks are still dequeued in FIFO order. However, when there are one or more reader blocks running, then a writer block may not be dequeued. While a single writer block is running, no other blocks may be dequeued, including other writer blocks. This guarantees that writer blocks have exclusive access and reader blocks may share access.

The new barrier blocks and user concurrent queues are immensely valuable. Lately, I've been considering how they relate to my recently developed Lockless Exclusion Accessor (LEA) design pattern. If you are not already familiar with my LEA pattern, you should first read my LEA article. The intent of a LEA is to make mutual exclusion easy and efficient. Since we want to be efficient, let's push efficiency further by allowing shared read access. Here is some generic code that does just that:

/// Block type to use when accessing the shared memory.
/// The type is 'id' just to be generic. With a real
/// LEA, you should use the exact type.
typedef void(^LEABlock)(id sharedMemory);

/// Class extension for holding the private, shared memory
/// and its associated queue.
@interface MyObject ()

@property (nonatomic, strong) id sharedMemory;
@property (nonatomic, assign) dispatch_queue_t leaQueue;

@end

@implementation MyObject

@synthesize sharedMemory = _sharedMemory;
@synthesize leaQueue = _leaQueue;

- (id)init {
    if ((self = [super init])) {
        // The queue MUST be concurrent to gain shared readership.
        dispatch_queue_t queue = NULL;
        queue = dispatch_queue_create(
          "com.RobBrown.LEAQueue",
          DISPATCH_QUEUE_CONCURRENT);
        [self setLeaQueue:queue];

        // Initialize shared memory here.
    }
    return self;
}

- (void)accessSharedMemoryReadWriteAsync:(LEABlock)block {

    // Block must not be nil.
    NSParameterAssert(block);

    // Executes the block asynchronously with exclusive access.
    dispatch_barrier_async([self leaQueue], ^{
        block([self sharedMemory]);
    });
}

- (void)accessSharedMemoryReadOnlyAsync:(LEABlock)block {

    // Block must not be nil.
    NSParameterAssert(block);

    // Executes the block asynchronously with shared access.
    dispatch_async([self leaQueue], ^{
        block([self sharedMemory]);
    });
}

@end

The first thing to note is that the dispatch queue is now concurrent instead of serial. If you use a serial queue then you will have no added benefits. The next thing to note is that every previous LEA in your object splits in two: a readonly version and a read write version. It's only four extra lines for a potentially great increase in efficiency.

As always, you should favor dispatch_async over dispatch_sync. If you must have synchronous access, then you can add synchronous variants too. You must, however, never use my dispatch_sync_checked function. It is not and never will be compatible with barrier blocks.

By introducing the readonly LEA, we now introduce a potential point of failure. What if we write some code that uses a readonly LEA, then we later change the code to modify the shared memory without switching to a read write LEA? This could introduce race conditions. If needed, you can add a sanity check to your readonly LEA. Here are a few options:
  1. If the object you are passing back has mutable and immutable variants, create two block types. The read write LEA will use the mutable variant and the readonly LEA will use the immutable variant. This is the best solution.
  2. If you don't have mutable and immutable variants, then you can simply pass a copy of the shared memory to the readonly block. This can potentially mask errors since you won't know if you accidentally use a readonly LEA when you meant to use a read write LEA.
  3. Before calling the block, you copy the shared memory. Then after calling the block, you check that the shared memory was not changed by comparing it to the earlier copy. If it was changed, then throw an exception. Although Objective-C rarely throws exceptions, this is an appropriate place to do so. Overall, this solution can be tedious work. You should also use a pre-processor macro to remove this check from release builds for efficiency.
  4. You can create a subclass of NSProxy. Instead of passing back the shared memory you can pass it the proxy. This proxy should throw an exception if any setters are called. This too can be tedious work. You may want to use a pre-processor macro here as well to remove the proxy in release builds.
Don't forget that user concurrent queues and barrier blocks are iOS 5 (and Mac OS X Lion) only. If you are using iOS 5 and you need mutual exclusion, I highly recommend using Read/Write LEAs (or at least regular LEAs). They make mutual exclusion fast and easy.

Monday, November 28, 2011

dispatch_sync_safe Deprecated

A while back I wrote a pseudo-category for GCD and posted it to Github. It contains several convenience functions. One of them was a method that makes synchronous calls “safe,” or so I thought. The code looked like this:

void dispatch_sync_safe(dispatch_queue_t queue, dispatch_block_t block) {
    // If we're already on the given queue, just run the block.
    if (dispatch_get_current_queue() == queue)
        block();
    // Otherwise, dispatch to the given queue.
    else
        dispatch_sync(queue, block);
}

The idea is that when doing a synchronous dispatch to a queue, I check if the program was already running on that queue. If it is, then the block is immediately executed. Otherwise, the block is run with a regular dispatch_sync. In my naïve implementation I thought this would prevent deadlock. The idea is nice but not correct. Consider the case when we dispatch_sync_safe to queue A. Next, we dispatch_sync_safe to queue B. Finally, we dispatch_sync_safe back to queue A. This is guaranteed deadlock.

As a result of this case, I immediately marked dispatch_sync_safe as deprecated in my Github repo. Anyone using this function thinking it is perfectly safe should think again. I did, however, add another function called dispatch_sync_checked. It is actually the same implementation as dispatch_sync_safe just under a different name. I recognize that this simple function has great value, but the old name was misleading. The moral of the story is, use dispatch_async (or one of my dispatch_async convenience methods) whenever possible. If you must run code synchronously, use dispatch_sync_checked and be very cautious of deadlock.

As I mentioned previously, dispatch_sync_checked still has great value. There is at least one case where you can guarantee you won’t deadlock. Consider the case when you have an object with a private serial dispatch queue. This queue is used to serialize access to some shared memory within the object. Using dispatch_sync_checked on the private queue allows you to keep your object’s methods synchronous and thread safe. This requires following two conditions in your critical code:
  1. Do not make synchronous calls to external objects (which could synchronously call the calling object again).
  2. Do not call dispatch_sync on any queue (or dispatch_sync_checked on any queue except the private queue).
Also, since these methods check for running on the private queue, they can call each other without worrying about deadlock. This gives similar behavior to a recursive lock without the overhead. If @synchronized(self) { … } just isn’t fast enough, consider switching to dispatch_sync_checked(_queue, ^{ … }).

Monday, October 17, 2011

My Philosophy on Language

When I was called to serve a mission in Canada for The Church of Jesus Christ of Latter-day Saints, I was called to English-speaking assignment. During my mission, I spent six months in a French-speaking assignment since I had taken three years of French in high school. After serving in that assignment for quite some time, I found that my thoughts had become detached from all language. This skill was useful (and probably resulted) because I spent all day switching between French and English. When I thought of something, I would mentally envision the object or idea rather than thinking of the English or French equivalent. This way I could mentally transition between languages without any loss of context.

I think language can limit our mental capacities. If we all view the world in the context of our native language, then we can only express ideas that already exist in that language. Language, however, is necessary so we can communicate our thoughts to others. Ironically, I must write this short article in a language, which makes it somewhat difficult to express such an abstract idea.

So, how does this relate to computer science? Programming languages are just as much languages as the natural languages, such as English or French. The difference is that programming languages can express different ideas from natural languages. Like natural languages, not all programming languages can express the same ideas. This may limit what you as a developer can mentally design and express. For example, if your language doesn’t support blocks, then you probably don’t know what continuations are. One reason that I like Objective-C so much is that it allows me to express many ideas freely, especially when playing with the dynamic runtime.

Likewise, if we only think in the context of our favorite programming language(s), then we can only develop ideas that already exist in that/those languages(s). By becoming detached from all languages (both natural and programmatic) we open ourselves to think of ideas that don’t exist yet. Once we create a new idea, we are then obligated to express that idea in a language or change our language to allow us to express that idea to other people. Again, the language we express our idea in can be natural or programmatic.

By the way, my ideas on language have a direct connection to The Five Orders of Ignorance by Philip Armour. Briefly, Armour argues that in order to ask questions and find answers about some idea, we must first develop a framework for thinking about that idea. I think that language is indirectly, and often directly, related to developing mental frameworks for thinking.

Thursday, October 6, 2011

A Tribute to Steve Jobs

The world is mourning the loss of a great man. I just hope that his great vision has not been lost as well. Steve lived his dreams. He was never content and continually pushed the boundaries of technology. His quest for perfection led to unparalleled products and user experiences. Perhaps it is best said of him what was said back in 1997:

Here’s to the crazy one. The misfit. The rebel. The trouble-maker. The Square peg in the round holes. The one who saw things differently. He wasn’t fond of rules, and he had no respect for the status quo. You can quote him, disagree with him, glorify, or vilify him. About the only thing you can’t do is ignore him. Because he changed things. He pushed the human race forward. And while some may see him as the crazy one, we see genius. Because he was crazy enough to think he could change the world, and he did!

Thank you for everything Steve Jobs. Because of you I have a job I love. The technology you developed has made life better and the world more connected. Through your example, others have strived to push their limits, including me. Rest in peace Steve and may God watch over your family.

Saturday, September 17, 2011

Lockless Exclusion Accessor Pattern

With all the work I have been doing with blocks and Grand Central Dispatch (GCD), I have developed a useful design pattern for handling mutual exclusion. I haven’t seen any patterns quite like this one, so I’ll claim it as my own.

Mutual exclusion is always a challenge when multithreading any application. GCD makes mutual exclusion substantially easier by using queues instead of locks. Nevertheless, there are still some challenges. When creating shared data I often include a warning in my documentation that it must only be accessed within a certain serial GCD queue. However, other developers that use my code may not read my documentation. Even I forget occasionally that some particular data isn’t thread safe. So, how do we make this easier? This is a situation for what I call the Lockless Exclusion Accessor pattern. I’ll call it LEA for short. (I also thought of calling it a “letter” since it’s closely related to a getter, but that seemed too silly and generic.)

Before going into the details of LEAs, we need to first understand why encapsulation is important. Most object-oriented languages have the ability to make variables private so they can only be directly accessed internal to the class. Limited access is given to the outside through getters and setters. This prevents classes on the outside making arbitrary changes to another classes internal data. To see how to encapsulate @propertys in Objective-C check out my @property article. We will apply the same principles to our shared data.

First, move your shared data into a class extension so it will not be externally visible. Second, you will want to typdef your block type. This keeps your code cleaner and easier to read. For this example, I’m going to use an NSManagedObjectContext as my shared data. So, my block typedef looks like this:

typedef void(^RBMOCBlock)(NSManagedObjectContext * moc);

Next, you need to create an accessor method. Outside classes will only be able to access your shared data through this method. It will look something like this:

- (void)accessMOCAsync:(RBMOCBlock)block {
        dispatch_async(dispatch_get_main_queue(), ^{
                block([self managedObjectContext]);
        });
}

The dispatch_async takes the passed in block and runs it on the main queue. We could (and really should) modify this code to run on a private serial queue instead. We also pass the shared data to the block. This grants the block exclusive access to that data (as long as the dispatch queue is a serial queue). You’ll also notice that this is an asynchronous call. If needed, we can also make a synchronous LEA. It looks nearly identical:

- (void)accessMOCSync:(RBMOCBlock)block {
        dispatch_sync(dispatch_get_main_queue(), ^{
                block([self managedObjectContext]);
        });
}

Now that we’ve built our asynchronous and synchronous LEAs, let’s use one.

[object accessMOCAsync:^(NSManagedObjectContext * context) {
        // Critical code goes here.
}];

That’s all there is to it. Just wrap your critical code in a block and you get exclusive, local access to the NSManagedObjectContext. LEAs are perfect for Core Data MOCs since they are not thread safe and are often the cause of much grief.

LEAs are also quite flexible. For example, you can merge multiple LEAs into one like this:

[object accessMOCAsync:^(NSManagedObjectContext * context, NSDictionary * userInfo) {
        // Critical code goes here.
}];

The above LEA gives the block exclusive access to two shared variables at once. You can extend this as far as you want. This way to don’t need to write multiple LEAs per class and you don’t need to nest LEAs. However, this comes with a tradeoff. You gain convenience at the cost of more contention for shared data.

Now, LEAs don’t perfectly protect shared data. It’s as good as Objective-C can get though. Rogue developers could pass the pointer to the MOC out of the block. They could also use the dynamic runtime to call the internal getters and setters. However, any developer doing either of these things is asking for a lot of trouble and should not be permitted to write Objective-C code.

For more GCD and block design patterns, check out these sources.


UPDATE:

I've removed all references to SyncSafe due to problems I've discovered.

Tuesday, August 23, 2011

iOS Recipes Review

Here’s a book I couldn’t recommend more. iOS Recipes by Paul Warren and Matt Drance has done more to improve my code than any other book.

Summary

iOS Recipes gives 40 code samples to improve common or useful iOS code. The recipes are grouped into five categories: UI, Table/Scroll Views, Graphics, Networking, and Runtime. The book is organized so you can read it in whatever order suits your needs. The wide range of recipes guarantees there is something that will benefit you.

Pros

iOS Recipes includes many code samples that can be dropped into any project and will just work without any extra modification. Any project could benefit from using at least one of the included recipes. For example, the common table view cell production/customization process typically takes 20+ lines of code. I now write the same code in 3 lines of code and it is fully Interface Builder customizable.

The greatest value of this book, however, is the explanation of how these recipes were designed. Warren and Drance explain exactly why they, for example, chose blocks over delegation or vice versa. By applying their same reasoning to other code, you can create your own quality recipes. This is further encouraged by not giving recipes that do everything. Some extensions are left as an exercise to the reader.

Cons

There’s nothing I can say against this book. It really is a great book.

Recommendation

Every experienced iOS developer should own this book. By following the principles taught in iOS Recipes, your code will increase in quality. I also recommend this book to any daring, young developers who are interested in gaining a deeper understanding of the full power of Objective-C and designing quality code.

Tuesday, August 2, 2011

Objective-C @property Best Practices

Now for my next rant on poor Objective-C code. Coming from other languages it's understandable that most developers don't take full advantage of the power of Objective-C 2.0. Here's a practice I hope that becomes more widespread.

Use @property

One feature of Objective-C that is underutilized is @property. The Objective-C compiler can write so much code for us, we just have to let it. Note that some of what I'm going to cover only works on the 64-bit (modern) Objective-C runtime. However, you probably won't find any situation where you need to write code for the 32-bit (legacy) runtime. The only reason we wrote legacy runtime code was because that’s what the iOS simulator used to run on (prior to iOS 4.0). That was fixed over a year ago.

Clean up your Headers

First, let's use @property to clean up our header files. The first thing to do is delete all of your ivars. Yes, delete all of them. They are no longer necessary. @synthesize will not only make your getters and setters, but it will also make your ivars. This was one of the major changes from the legacy to modern runtimes. This is nice because we don't need to be redundant about our instance variables anymore. Now, for all of your public ivars, make an equivalent @property. We'll handle the private and protected ivars in a moment. With just your public @propertys, your headers will now be much shorter and easier to read. Remember, headers are for public information. That is the whole idea behind encapsulation. You don't want your private information in your public headers. Even though I'm focusing on @propertys, you can apply the same ideas to methods too.

Categories and Class Extensions

Before handling your private and protected ivars, you need to understand categories and class extensions. If you feel comfortable using class extensions, feel free to jump to the next section.

A category is a way to extend the interface and functionality of an existing class. You declare them similarly to regular classes:

// MyClassAdditions.h

#import "MyClass.h"

@interface MyClass (CategoryName)

// Extra method declarations.

@end


// MyClassAdditions.m

#import "MyClassAdditions.h"

@implementation MyClass (CategoryName)

// Extra method implementations.

@end

Making a category is that simple. You just need to remember to #import your category when you want to use your extra methods. Class extensions, for all intents and purposes, are categories. The main differences are that only the original class can create a class extension for itself and you can declare @propertys in a class extension. So we will do just that. To create a class extension you simply create a category with no name. It will look something like this:

// MyClass.m

@interface MyClass ()

@property (nonatomic, copy) NSString * myPrivateString;

@end

With your class extension in place, you just need an associated @synthesize myPrivateString; and you're done. It's that simple. You can do this with all of your private class variables with no problems.

Protected Data

Now we are left with the protected variables. These are a little more tricky. Technically protected variables and methods don't exist with this technique. Then again “private” technically doesn't exist at all in Objective-C. The runtime won't stop you from calling private methods. Anyway, you should avoid protected data as often as possible. Sometimes that just isn't possible though. If you want a protected @property, just put it in your class extension like your private data. Then, any subclasses that need to access the protected property need to contain an identical @property in their class extensions. You will want to include some documentation about your protected @property. This does seem a little redundant to have identical @propertys, but it's bearable since Objective-C generates the important code for you. Again, this also works for methods. This is particularly nice because the @protected key word doesn't work on methods like it does ivars. One thing to note is that you can't call super in a protected method using this technique (you will get an annoying warning). If you need to make a super call, then your protected method should be placed in a private header instead. This private header should contain just the prototypes and is ONLY imported by classes that need that information.

Readonly Getters

What about when you want to make a public getter but a private setter? Objective-C can do this for you too. In your public header you can do something like this:

@property (nonatomic, copy, readonly) NSString * myPrivateString;

Then in your class extension you make a similar declaration:

@property (nonatomic, copy, readwrite) NSString * myPrivateString;

You just need to make sure the two declarations mirror each other (i.e. nonatomic and nonatomic, retain and retain, copy and copy, etc.). From there you just use @synthesize and Objective-C takes care of the rest.

Other @property Modifiers

While speaking of @property modifiers, I should take a moment to discuss them for anyone unfamiliar. You may skip to the next section if you already know the modifiers. By default an @property is atomic, assign (or weak), and readwrite. I've never found a good reason for atomic. Atomic just means that Objective-C is going to use a lock to enforce thread safety. This will make your getters and setters slower since it has to acquire and release the lock. If you are using single-threaded code this is completely unnecessary. If you are using multi-threaded code, you really should be using Grand Central Dispatch (or NSOperationQueue) to take advantage of lockless exclusion.

The next modifier is copy/retain/assign. For almost everything you do, you will use retain. It's good to know the exceptions though. When you have an NSString, NSArray, NSSet, or other object with mutable/immutable variants, you should use copy instead. If the object is immutable, it will be retained for efficiency, otherwise it will be copied.

Assign (or weak when using ARC) also has some uses. Mostly you will use it when dealing with primitives, such as BOOL or int. Since they aren't objects you can't call -copy or -retain on them. You will also use assign when you have want to avoid a retain cycle by creating a weak relationship. This is common with delegates.

You can also specify the names of your getters and setters. You specify getter=myGetterName or setter=mySetterName. This is often used with BOOLs. For example, you may create a property like this:

@property (nonatomic, assign, getter=isOn) BOOL on;

Dealloc

When writing your -dealloc methods, you may wonder how you can release your instance data without direct access to your ivars. There is only one reasonable way to do this. You should call [self setMyProperty:nil];. This will set your ivar to nil and consequently release the old value.

Exceptions

All rules have their exceptions including @property. If you need to make a custom getter or setter, you will need to create an associated ivar. Technically you can actually access synthesized ivars directly. However, Apple considers this to be a “bug” and access to synthesized ivars may disappear in the future. You can add ivars to class extensions for your private properties. Be aware, though, this is only supported on Clang/modern runtime and may require additional settings.

Benefits

Now that we've gone over all that, let's go over the benefits of these extra techniques:

1. The obvious benefit is the compiler will write your getters and setters for you. The compiler not only writes your getters and setters but also makes them Key-Value Observing (KVO) compliant. This means you can observe the changes of any property on an object. KVO is especially useful when writing Model View Controller (MVC) code. Controllers can watch model objects for any changes and update the views as appropriate.

2. You will have less memory bugs. When writing your actual code, you should always use your getters and setters instead of accessing ivars directly. This will make most of your memory management bugs disappear instantly. You won't need to remember to call retain/copy and release with your ivars. Your synthesized getters and setters will do that automatically for you.

3. Your code will be better encapsulated. I've seen too much code where I've had to guess which ivars (and methods) I could safely use due to a lack of organization and no documentation.

4. Last, but not least, your code will be more readable. Your headers won't be cluttered with private and protected data, and your implementation files won't be cluttered with standard getters and setters. Furthermore, your files will be better organized. You will know exactly where to find your public, private, and protected data.

Employ these techniques and they will serve you well. Other people who have to use your code after you with thank you too.

Credits

The ideas in this article were strongly influenced by the Apple docs, iOS Recipes Recipe 35, various WWDC videos, and a lot of personal experience (i.e. bugs).

----
Update: August 23, 2011

I have further refined and corrected this article through further study and experience on the topic, particularly ivars and custom accessors.

Saturday, July 30, 2011

One singleton to rule them all

One of the most common design patterns is the singleton. However, implementing singletons, especially in Objective-C, can be very repetitive. I often forget how to properly override all the memory management methods and need to look up a previous singleton. One of the goals of programming is to automate the repetetive, mundane tasks. Cocoa With Love has a great synthesized singleton made from a C pre-processor macro. The problem with this is that it's not flexible. So, I made an Objective-C singleton that can be dropped in any project. By subclassing RBSingleton you can gain all the benefits of a singleton without adding any further code and you have full flexibility to customize each subclass.

There are two main parts that make RBSingleton possible. First, it stores all the singleton instances in a class-wide dictionary. A singleton typically keeps a static pointer to the singleton instance. This works fine as long as it's not subclassed. When subclasses become involved, the subclass that allocates first defines the singleton instance for all subclasses. This restriction is normally beneficial to singletons, but breaks with subclassing. I could have required subclasses to provide a pointer to a static class pointer through a method call, but this imposes more on the subclass's implementation than I wanted. By using a class-wide dictionary, every subclass can store its singleton instance under a unique key. To guarantee a unique key, I simply use the subclass's name.

Second, the singleton instance is allocated by dynamically calling NSObject's -allocWithZone: method as shown below.

Method allocMethod = class_getClassMethod([NSObject class], @selector(allocWithZone:));
sharedInstance = [
method_invoke(self, allocMethod, nil) initialize];

The trick here was to allocate the singleton as the class of the RBSingleton subclass but use NSObject's -allocWithZone: method to do so. This is similar to calling [super allocWIthZone:nil];. The difference is that it's jumping more than one level in the inheritance hierarchy. This is known as a grandsuper call. The Objective-C dynamic runtime makes it possible to make such a call. You will also notice that I hardcoded [NSObject class] into the code. I could have dynamically discovered the root class with the following code:

+ (Class)rootClass {

        
Class rootClass = nil;
        
Class currentClass = [self class];

        
while ((currentClass = class_getSuperclass(currentClass)))
                rootClass = currentClass;

        
return rootClass;
}


If I instead needed to get a grandsuper class that isn't necessarily the root class and I know a subclass of the grandsuper I could use simpler code like this:

[RBSingleton superclass];

Since I know the specific grandsuper class I need, I hardcoded it for efficiency. If you use RBSingleton and find a need to dynamically discover a particular grandsuper class, you can use the above code to do so. I've uploaded RBSingleton as a Gist and you can find it here.

One last note, to use RBSingleton you need to include libobjc.dylib for the dynamic runtime calls.

Tuesday, July 26, 2011

#define Abuse

Lately I've been encountering some terrible Objective-C code, and I have a few words to say about it. One of the first problems I've found is the overuse of #define. Don't get me wrong, #define has its place, but when it comes to constants #define should not be the first choice.

Anti-Patterns
One of the problems with #define is that it's simply a macro substitution. There is generally no type associated with the value. This makes is harder for the compiler to warn you of potential errors. Macros can also have side effects you may forget about. For example:

#define MY_STRING_CONSTANT [[NSString alloc] initWithFormat:@"Hello World!"] // Very bad.

The above example will cause a memory leak unless you remember to release the value each time. Just a side note, Apple's static analyzer will pick up this error if you turn it on. I should also mention that the following, related example is not preferable. I have actually seen this used in production code before.

#define MY_STRING_CONSTANT [NSString stringWithFormat:@"Hello World!"] // Still not great.

Numbers
With a couple anti-patterns out of the way, let's go over the proper way to define constants. You will find that it doesn't take much more effort to properly define constants. Numbers are the simplest and one of the most common, so we'll start with them. In your .m file (applies to .c or .cpp too) you will define your constant like the following:

const NSInteger kMyInt = -100;
const NSUInteger kMyUnsignedInt = 42;
const CGFloat kMyFloat = 3.14;

You could instead use 'int', 'unsigned int', and 'float' if you prefer, but the above types are generally the preferred data types. If you want to keep your constant visible to just your implementation file, then you are done. If not, you need to do one last thing. In your header file, you will need to use the following:

extern const NSInteger kMyInt;
extern const NSUInteger kMyUnsignedInt;
extern const CGFloat kMyFloat;

The reserved word 'extern' makes a promise to the compiler. You are letting the compiler know that you are not defining the value right away, but at link time, that value will exist. In this case, it's defined in your implementation file. With that in place, you are now done; your constant is defined and other classes can #import (#include for C and C++) your header file and use your number constants.

You may wonder why you can't define the constant right in your header file. If you do, you will get an error message that looks like this: "ld: duplicate symbol <Constant Name> in <File 1> and <File 2>." Generally #import handles duplicate imports properly; however, it doesn't work for constants. I figure this error is why developers unaware of 'extern' default to #define.

Enumerations
Closely related to numbers are enumerations. If you ever have a series of related number constants, you probably want an enum. For example:

// A contrived example but should get the idea across.
enum {
        kJanuary = 1,
        kFebruary = 2,
        kMarch = 3,
        kApril = 4,
        kMay = 5,
        kJune = 6,
        kJuly = 7,
        kAugust = 8,
        kSeptember = 9,
        kOctober = 10,
        kNovember = 11,
        kDecember = 12,
};

Enumerations are great for bit masks too.

// Another contrived example.
enum {
        kBit1 = 1 << 0,
        kBit2 = 1 << 1,
        kBit3 = 1 << 2,
        kBit4 = 1 << 3,
};

Enumerations are where type checking really helps. Say you are using a switch statement, the compiler can warn you if you didn't include one of your enum values as a switch case.

Strings
Strings are also very common in Cocoa programming. There is one extra detail that makes them different from numbers. At first you may want to make a constant like this:

const NSString * kMyString = @"Hello World!"; // Wrong - String Anti-Pattern 1

This is wrong for a couple different reasons. First, NSString is immutable, meaning that it can't be changed. This essentially makes it a constant by default. However, there is a big flaw with the above anti-pattern. I will first show the proper way:

NSString * const kMyString = @"Hello World!"; // Right

At first glance, you are probably wondering why 'const' is next to the constant name. The difference between the number and string examples is that the NSString is a pointer. The first string example tells the system that the value @"Hello World!" can't change, but the pointer value can change. You probably wouldn't, but you could do the following:

kMyString = @"Goodbye World!"; // Very bad, but allowed in String Anti-Pattern 1.

You didn't change the value of @"Hello World!", but you did change what kMyString pointed to. That doesn't sound like a constant at all.

By the way, the following is also permissible, but wrong.

const NSString * const kMyString = @"Hello World!"; // Wrong - String Anti-Pattern 2

This makes both the value and the pointer constant. However, the first 'const' changes the data type of the constants. None of the Cocoa frameworks accept a const NSString * (since it's redundant). This means that you will have a compiler warning anytime you try to pass your constant to a Cocoa framework method. You might do something similar with other objects, but in Objective-C, such cases should be very rare. This is something more common in C or C++.

Objects
Objects other than strings can be a little more tricky. You can't do the following:

MyObject * const kObject = [[MyObject alloc] init]; // Wrong - Object Anti-Pattern 1

The problems is the right-hand side does not evaluate to a compile time constant. Furthermore, if it was possible, it would be difficult to configure the object properly. This requires a different technique.

// Right
+ (MyObject *)MyConstObject {

        static MyObject * obj = nil;

        if (!obj) {
                obj = [[MyObject alloc] init];

        // Any other initial setup.
        }

        return obj;
}

Looking at the return type of MyObject *, you may think this has the same problem that String Anti-Pattern 1 had. This is not the case here. The original constant pointer is protected within the method; it can't be changed externally. When you call the method, you receive a copy of the object's address. You can change it if you want, but it won't affect anyone else. Naively you may want to change the return type to MyObject * const, but a const pointer doesn't affect the data type. You could do the following regardless:

MyObject * obj = [[self class] MyConstObject]; // Type MyObject * is the same as MyObject * const

One last note about object constants is that they are technically memory leaks. However, they are permissible for the same reason that singletons are permissible. What's more interesting is that Apple's latest static analyzer now flags singletons as memory leaks but still doesn't catch the above constant.

When to use #define
I should probably include a kind word about #define. If you want to use any pre-processor macros such as #if or #ifdef, then #define is your only choice. #define is also good for simple, inline functions or when you want to write some code that will do automatic renaming (see Cocoa With Love's synthesized singleton). #define has countless valuable uses, but when it comes to constants, try something else first.

Tuesday, July 19, 2011

Driving Technical Change Review

One particular book that caught my eye some time ago is Driving Technical Change by Terrence Ryan. In his book, Ryan teaches the skills necessary to convince others to adopt your ideas. Though the book focuses around technical fields, most of the skills taught apply to other disciplines.

Summary
Ryan begins his book by classifying different types of people, such as the Cynic, the Uniformed, and the Irrational. From there he progresses to the skills needed to use on the different categories including delivering your message, gaining trust, and getting publicity. Ryan then concludes with how to strategically employ the needed skills.

Pros
The book is written in a way that it can in whatever order fits your needs. Once you have identified the category (or categories) of people you are working with, you can jump straight to the recommended skills and techniques. The chapters are short and easy to read. Every skeptic category and rhetoric technique includes short examples to illustrate the ideas.

Most of the ideas covered seem common sense. Yet there are some examples that I had never thought of employing. For example, Ryan suggests one way to get coworkers to accept a framework you've built is to open source it. If many people start using it, or even contributing to it, then your coworkers will be much more open to using your framework.

Cons
Ryan tends to dodge confronting the Irrational. It is true that little can be done to convince an irrational person. However, he doesn't offer many suggestions besides avoid them and/or have management mandate a policy. Management mandate may be the silver bullet, but what about the situation when management is irrational? Perhaps the best solution at that point is to find a new job.

Before reading this book, I was expecting Ryan to go into more detail on leadership skills. However, many skills such as gaining trust are left with few examples or explanation of how to gain trust. I do like the succinctness of Ryan's writing, but sometimes I'm left wanting more concrete examples.

Recommendation
If you are one of the many that feel your voice isn't heard, this book likely has some skills you haven't tried yet. Ryan shares his secret to leadership: "you can be promoted to management, but no one appoints you a leader." Driving Technical Change can help you take initiative and become a leader.

You can purchase Driving Technical Change here from The Pragmatic Bookshelf.