Safe Casting in Objective-C

I’m writing a small safe casting for Objective-C. I’ll be putting it on GitHub

The Story

Somewhere on the web, there was some test I took to determine how well I know Objective-C. I think it was elance. One question which infuriated me at the time was something like “if you have an array NSArray *a, how do you make it an NSMutableArray?” The reason I got angry was that the answer was supposedly

NSMutableArray *mutableArray = (NSMutableArray *)a;

Except that this is tremendously dangerous, wrong, stupid, crazy… well. You get the picture. The real answer of course is something like

NSMutableArray *mutableArray = [a mutableCopy];

Unless you want to actually modify the same instance that a is if it’s a mutable array, in which case you have to do the all-too-familiar dance

NSMutableArray *mutableArray;
if ([a isKindOfClass:[NSMutableArray class]]) {
    mutableArray = a;
}

At which point you proceed to mutate mutableArray, which is also a, possibly ignoring the fact that mutableArray may be nil. Or maybe you return early if it’s nil.

Casting is Dangerous

If you cast between object that are the same foundational type, no work is done. What I mean is that if you cast from ...

OHMKit

I’ve written Objective-C code to turn a service response into a fully hydrated model object too many times. It also seems I’m not the only one. Just a couple of weeks ago, I decided to put together OHMKit so I’d never have to write boilerplate code for object mapping again.

Check out the source on GitHub!

OHMKit is a mixin to make any Objective-C class easier to hydrate from a dictionary representation, such as you might get from a web service. It makes it easy to keep any direct knowledge of the idiosyncrasies of the service you’re consuming tucked away in a single place.

It exists because RestKit (which is awesome by the way), is sometimes too big, heavy, and indirect.

This project doesn’t know about networks. Use AFNetworking.

This project doesn’t know about routes. Use SOCKit.

This project doesn’t know about CoreData. It will not manage graphs of entities for you quite like RestKit does. But it is built on KVO, and does not care about your model objects’ super class. So you can safely make subclasses of NSManagedObject mappable.

Usage

Basic Mapping

Given a model

@interface MYModel : NSObject
@property (nonatomic, strong ...

Per File ARC in CocoaPods

tl;dr

Pod::Spec.new do |s|
  s.name = 'MyPod'
  ...
  non_arc_files = 'Classes/FirstNonARCClass.m',
    'Classes/SecondNonARCClass.m',
    'Classes/ThirdNonARCClass.m'
  s.requires_arc = true
  s.source_files = 'Classes/*.{h,m}'
  s.exclude_files = non_arc_files
  s.subspec 'no-arc' do |sna|
    sna.requires_arc = false
    sna.source_files = non_arc_files
  end
end

ARC

Automatic reference counting (ARC) is a good thing. It's a great compile-time technology that makes it easier, in most cases, to not accidentally introduce trivial memory leaks in modern Objective-C apps.

But sometimes, you have older code with traditional memory management; it's not really worth converting to ARC if it's correct, and possibly finely tuned. And sometimes ARC introduces a little unnecessary overhead that can balloon out of control when handling large numbers of objects. There are also good reasons to put Objective-C objects into structs or other odd places that ARC prohibits or makes difficult (Objective-C++ anyone?).

That said, ARC is almost always a good idea. And so disabling ARC should be the exception, not the rule.

CocoaPods

CocoaPods is an excellent dependency management system for Objective-C projects. Dependencies are distributed as 'Pods' which are described in podpecs. A podspec is a kind of build description, that specifies where the source ...