views:

159

answers:

3

How do you deal with deprecated methods in iPhone that require you to use a newer method, not available in older versions?

Consider the case of setStatusBarHidden:animated:, which was deprecated in iOS 3.2. The documentation points you to use setStatusBarHidden:withAnimation:, which is only available in iOS 3.2 or later.

If I understand correctly, this means that to target all devices (iOS 3.0 or later), I have to ask first if setStatusBarHidden:withAnimation: is available. If it is, use it. If not, use the deprecated method. But I would still get a warning of deprecation.

Is this correct (please say it isn't!)? If it is, is there any way to suppress this deprecation warning, or to indicate the compiler that I have already handled the problem?

A: 

Probably there is a better answer, but what I did once was:

1 check if the deprecatedMethod is available. (using respondsToSelector: method)

2 if yes then call that method using objective-c runtime function:

id objc_msgSend(id theReceiver, SEL theSelector, ...)

when using this function the compiler won't give you any warnings :)

3 other wise use the new method

nacho4d
+1  A: 

I found a similar question that assumes that yes, this is the correct way of dealing with deprecated methods, and no, there is no way to suppress deprecation warnings on a per-case basis, but there are hacks to mislead the compiler.

To deal with the example case, I decided to create an util class using one of these hacks:

@protocol UIApplicationDeprecated

- (void) setStatusBarHidden:(BOOL)hidden animated:(BOOL)animated;

@end

@implementation UIUtils

+ (void) setStatusBarHidden:(BOOL)hidden animated:(BOOL)animated {
    if([[UIApplication sharedApplication] respondsToSelector:@selector(setStatusBarHidden:withAnimation:)]) {
        [[UIApplication sharedApplication] setStatusBarHidden:hidden withAnimation:animated ? UIStatusBarAnimationSlide : UIStatusBarAnimationNone]; 
    } else { 
        id<UIApplicationDeprecated> app = (id)[UIApplication sharedApplication];
        [app setStatusBarHidden:hidden animated:animated];
    }
}

@end

If I'm not mistaken using respondsToSelector is costly. This could be optimized for performance to remember if the new selector is present after the first query, thus avoiding the need for reflection in subsequent calls.

Coming for a Java background, I find this way of dealing with deprecation appalling and I still can't believe that this is how iOS designers expect us to deal with this problem. More thoughts on the subject will be much appreciated.

hgpc
A: 

Invoking method this way:

id objc_msgSend(id theReceiver, SEL theSelector, ...)

will be better choise in case you want to omit warning that UIApplication may not respond to setStatusBarHidden:withAnimation: method (in iOS 3.0 or later).

plug-in