views:

231

answers:

1

In the iPhone SDK 3.2, [CLLocation getDistanceFrom:] was renamed to [CLLocation distanceFromLocation:]. My project is compiled with 3.2 as the Base SDK and a "Deployment Target" of 3.0, meaning frameworks only available in 3.2 are weak linked so my app can still run on 3.0.

If I change my calls to use the new name distanceFromLocation:, what will happen on devices running 3.0 or 3.1? I assume that the method call will fail and 0.0 will be returned (as Cocoa returns the default for unrecognized selectors).

If my assumption is correct this means I have to live with the compiler warnings for now, until I no longer want to target 3.0.

+3  A: 

If I change my calls to use the new name distanceFromLocation:, what will happen on devices running 3.0 or 3.1? I assume that the method call will fail and 0.0 will be returned (as Cocoa returns the default for unrecognized selectors).

No, you're thinking of sending messages to nil. Sending a message to an object that doesn't recognize the selector will cause an exception. If you don't catch that exception, your application will crash. Users will not like this, and Apple may reject your app over it.

The solution is to test whether the location responds to the new selector:

if ([here respondsToSelector:@selector(distanceFromLocation:)])
    distance = [here distanceFromLocation:there];
else if ([here respondsToSelector:@selector(getDistanceFrom:)])
    distance = [here getDistanceFrom:there];

Incidentally, this really doesn't have anything to do with linking. If we were talking about a class that had changed names, then it would be, but dynamic message dispatch means Objective-C “method calls” (more precisely, messages to objects) are not bound at compile or link time.

Peter Hosey
Thanks Peter, you are correct on both counts.
Adam Ernst