Treat Compiler Warnings as Errors

I’m a big believer in the compiler option to treat warnings as errors.  Compiler warnings are our first line of defense against inadvertent screw-ups in our code.  It means you’re probably doing something wrong, or that goes against recommended practices.  ie: “Sure, technically you can do this but it might result in unexpected behavior, memory leaks or other problems if you’re not careful.”  So turn on “warnings as errors” to prevent accidents.

The warning may just be a “head’s up”–like an unused variable warning.  Maybe you forgot to use it somewhere in your code.  Maybe you did some refactoring and no longer needed it.  In this case just fix your code.

There may be cases where you understand better than the compiler what you’re trying to do, and you do want to exploit a capability of the compiler to do something you think is really clever.  (We programmers do like to be clever, don’t we?)   Chances are you’re wrong though and you should probably find a different way.  The next version of the compiler might be more strict–or worse, might behave in a different fashion in this case and cause a change in your code’s behavior, often for the worse.  If you want maintainable code, treat the compiler’s warnings seriously.

However, if you are absolutely certain you know what you need to do and there’s no alternate way to accomplish your code, then don’t turn off the “warnings as errors” build setting, and don’t turn off the warning globally.  Just turn it off for your one risky piece of code and document it.  eg:

#pragma clang diagnostic push
// Turn off the "undeclared selector" warning because we're
// checking to make sure that the target responds to that 
// selector before trying to perform it.
#pragma clang diagnostic ignored "-Wno-undeclared-selector"

if ([target respondsToSelector:@selector(doSomethingCool)]) {
    [target performSelector:@selector(doSomethingCool)];
}

#pragma clang diagnostic pop

Notice that while I’m exploiting this ambiguous compiler behavior I’m also being careful to avoid misusing it!

Finally, there may be a situation where third party code has some warnings. One option would be to fix the warnings and submit a pull request to the owner. This might not always be feasible though (or you simply don’t have time to fix someone else’s code). You can also turn the offending warning(s) off on a per-file basis. This is nice because the configuration change goes into your project settings, not the third party source. This could help avoid merge conflicts or having to re-apply your changes when updating the third party source to a newer version.

In Xcode select your target and go to the “build phases” tab. Search for the name of the offending file and double-click on the “compiler flags” field (to the right of the file name). Enter the flag to disable the offending warning, eg: -Wno-undeclared-selector.

Disabling a compiler warning on a per-file bases.

Disabling a compiler warning on a per-file bases.

Lastly, it’s not always easy to know what the name of the compiler flag is for the warning you disable. Your compiler should have documentation about this, as do the Internets. Try searching for the error message and “disable”. It’s very likely someone else has had this problem and already found the compiler flag for you. And if you don’t get any results it may be a sign that you’re doing something inadvisable.

Thread This!

Today I wrote a utility to ease the use of dispatch queues and GCD (Grand Central Dispatch) in Objective-C.  GCD is very powerful, but it’s written in C and I often find there’s a lot of boilerplate code required in order to use it.  So I wrote a light wrapper called NHThreadThis which makes it a bit easier.  Of course the provided source code has unit tests and a sample app.

@todo: dispatch I/O and sources API support!

How to StackOverflow

I recently read an interesting post on using StackOverflow as a hiring metric, something I think has some merit.  It actually encouraged me to start regularly contributing back to the community, instead of just lurking.  However, in my recent experiences I’ve noticed two categories of questions:

  1. People who have dug into the documentation (for the language, OS, a third party SDK, or whatever technology they are trying to get to work) and then post a well-thought out question (with code and stack traces, if appropriate).
  2. People who want the community to do their homework for them (in some cases, quite literally so).

I’m all for contributing to the community, and I think everyone should be free to post their questions.  But the way to do StackOverflow questions correctly is to take the first approach.  Do some investigation first, and if you can’t figure it out on your own then post your question–and do it in a way that will help us help you.

If you post something like #2 I’m going to continue to ignore your posts, or vote them down.  I actually gain something personally from working on questions like #1.  Sometimes I learn something new, or in framing an answer it helps clarify in my mind some information I haven’t used recently.  I get nothing from posts like #2.

xcode-select is your friend

If you’re an early adopter using Xcode 5 developer preview but need to use the Xcode 4 command line toolchain, xcode-select is your friend.  Use this command to switch the toolchain back to your Xcode 4 install:

sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer

Concurrency in iOS

There are many and more articles on concurrency in iOS and Objective-C, but I think this is a great one.  However, I recommend skipping over the talk about threads and go straight to GCD and NSOperationQueue.  There’s really no reason to manage your own threads any more (unless you’re porting over some code to iOS)–unless of course you like debugging hard-to-find threading issues in your app!

One further caveat: the section which discusses managing shared resources could use a little improvement.  It is correct that traditionally one uses a lock to manage access to a shared resource.  However, there is a much better way to do this in iOS, and that is with GCD and a serial queue.  Consider the following code example:

@implementation MyController ()
@property (nonatomic, assign) dispatch_queue_t sharedResourceQueue;
@property (nonatomic, assign) NSUInteger sharedCounter;
@end

@implementation MyController

- (id)init {
    if ((self = [super init])) {
        _sharedResourceQueue = dispatch_queue_create("com.myidentifier.MyCoolApp.sharedResourceQueue", DISPATCH_QUEUE_SERIAL);
    }
    return self;
}

- (void)dealloc {
    dispatch_release(self.sharedResourceQueue);
}

- (void)accessSharedResourceSynchronously {
    dispatch_sync(self.sharedResourceQueue, ^{
        // safely access my shared resource and block the calling thread
        self.sharedCounter++;
    });
}

- (void)accessSharedResourceAsynchronously {
    dispatch_async(self.sharedResourceQueue, ^{
        // safely access my shared resource but don't block the calling thread
        self.sharedCounter++;
    });
}

In the above example I’m creating a serial dispatch queue and managing access to the shared resource by using dispatch_sync() and dispatch_async(). Because the serial dispatch queue guarantees that any blocks executed on it will happen in order, I can ensure that the shared resource is not accessed simultaneously (as long as I don’t abuse this elsewhere in my class).

Why is this better than using @synchronized or NSLock? Because both of those require a kernel interrupt, which is going to cause a context switch and reduce your app performance. Dispatch queues are handled entirely in-process and don’t have the overhead of a kernel interrupt. You get the behavior of a lock without a performance hit.

Of course, you still need to watch out for deadlocks, but that’s a pitfall with managing access to any shared resource with concurrency.

There is even more great advice on using dispatch queues in this follow-up article, including a great pattern for multiple readers and a single writer.  My example is a trivial one, but using dispatch_barrier_async() will greatly improve performance by waiting to write until all the reads are finished.

WWDC 2013 Top Ten

I was one of the lucky ones who attended WWDC 2013 this year.  (Pro tip: copy your Apple ID password to the clipboard so you can sign in very quickly and order your ticket.)  As always there is a lot of information about new products, OS updates, innovations and APIs.  Below is a round up of some of the most important developments in iOS development from Apple.

  1. Bots.  Apple has finally made continuous integration a breeze.  In the past I have used Jenkins to set up a continuous integration system–but it was a lot of work which required a great deal of manual configuration.  With XCode 5 and OS X Server you can use Bots to easily build a continuous integration system and even have a “scoreboard” which shows stats on the state of your build.
  2. XCTest.  Apple has upgraded their unit test framework and made testing your code easier than ever.
  3. XCode 5.  Built on ARC the new XCode should take up less memory and run faster than before.  They’ve streamlined the interface and included some new built-in profiling tools to help catch memory leaks and performance issues while you’re developing.  Instruments is still there with its rich tools, but now XCode has an early warning system while you’re debugging.
  4. New Background Features.  Background transfer means that the OS will download (or upload) your data for you while your app is in the background.  This is huge for data-intensive apps!  Read up on NSURLSession to find out more.  Remote Notification allows you to send a push notification to your app and wake it up to perform a task.  Background Fetch tells the OS to periodically wake your app and give it a chance to update its data, so that whenever the user brings it to the foreground it has up-to-date information to present to the user.
  5. UIKit Dynamics.  iOS has always had rich animation support, but now it’s easier than ever to create dynamic and engaging interactions in your app.  And for gamers check out SpriteKit (Cocos2D watch out). It even has a particle effects editor!
  6. Inter-App Audio.  CoreAudio has some cool new features that allow audio-enabled apps to share audio between each other.  This is very similar to AudioBus–but works directly with the OS and doesn’t require a third party library (which makes me wonder what’s going to happen to the innovative AudioBus app and framework).
  7. Collection View Layout Transitions.  There is some really cool stuff you can do in iOS 7 with collection views and layout transitions.  Check out the iOS 7 photo app or calendar for examples!  This new feature will let you seamlessly transition from one layout to another within the same collection view.  Instead of pushing a new view onto a navigation controller the existing collection view can animate to a new layout and present a detail view within a larger context–giving users a better sense of place.
  8. Custom Navigation Transitions.  Have a great idea for a navigation controller transition?  Now you can build it.  There are a lot of details here, and it looks pretty complicated, but if you follow the rules it looks like it will work pretty smoothly and save you the trouble of building your own navigation UI.
  9. State Restoration.  This has existed since iOS 6 but there are some new features that make it more powerful and easier than ever to let iOS restore your app to its former state when it is re-launched.  Combined with snapshots this makes your app seem like its process never got killed.
  10. Game Controller Support. This looks awesome for the gaming crowd. Watch out console makers! Did I mention SpriteKit makes it easy to build awesome 2D games?

PS: be sure to check out the WWDC 2013 videos online!

 

How To Be a Lead Developer

In my transition from collaborator to team leader I’ve figured out a few techniques that I find effective.  What follows are what I’ve found to be some effective practices for running a software development team (this is for a purely dev team–I have some thoughts on QA as well, which I will address at a later date).

  1. Everyone has their own fork of the code repository (eg: How to fork on GitHub).
  2. Have a good branching scheme.
  3. Have a continuous integration system (like Jenkins)–fire off a new build every time a commit is merged to the main repository’s develop branch.
  4. Configure your compiler settings to treat warnings as errors.
  5. Use Test-Driven Development, or else waste time chasing down random bugs whenever someone introduces a change.
  6. The lead helps coordinate and unblock developers.
  7. The lead helps plan and schedule the user stories with the product owner and scrum master.
  8. The lead relies on the team to come up with designs, but provides guidance on the design–generally with an eye toward not over-designing, doing the minimum necessary without cutting corners.
  9. A user story is not complete without unit tests.
  10. When you find a bug, fix it and add a unit test to check it.

There is undoubtedly more than this, and I hope to expand on a few of these points in the future.  As you move into a lead position your job is less about writing all the code and more about coordinating the code that others generate.  I still write some code, but at least half my time is taken by supervising others’ code–making sure there is a cohesive design and that the pieces fit together.  It is a different sort of problem than writing the code, but it is a fun challenge.

Fix Your Xcode Project Index

I’m a fan of the new Xcode 4. However, sometimes the editor seems to “forget” my project’s symbols–preventing auto-completion and symbol lookup (including the quick-open feature, which I use a lot). Here’s a useful solution if you find yourself in this situation. Select your project in the Xcode Organizer and delete its “derived data.” It’s annoying but does the trick.