12

I need to deprecate a single method in objective-c protocol. On normal class/instance methods I add __attribute__ ((deprecated)); after declaration.

It seems, that it does not work on protocol methods. If I mark them deprecated and use them somewhere the project compiles OK, without expected deprecation warning.

Is it a flaw in Apple LLVM 3.1, or am I doing something wrong?

Vilém Kurz
  • 3,401
  • 2
  • 34
  • 43
  • This still occurs in LLVM 5.0. Although the compiler does not show a warning, it crosses out the method with a red line when using Xcode auto-complete. Any word on this? – Sam Spencer Nov 24 '13 at 19:59

3 Answers3

7

Although the answers here provide some very good information, they are outdated. Starting with Xcode 5.0 and LLVM 5.0 it looks like deprecation warnings for Objective-C protocol methods are recognized. When implementing the method, Xcode 5 flags it:

Warning: Implementing deprecated method

Here are the steps I used to produce a deprecation warning for the implementation of a deprecated protocol method:

  1. Mark the protocol method as deprecated using __deprecated. From the new SDK 7.0 documentation:

    __deprecated causes the compiler to produce a warning when encountering code using the deprecated functionality. __deprecated_msg() does the same, and compilers that support it will print a message along with the deprecation warning. This may require turning on such warning with the -Wdeprecated flag. __deprecated_enum_msg() should be used on enums, and compilers that support it will print the deprecation warning.

    #define __deprecated    __attribute__((deprecated))
    

    To deprecate your method, do something like this:

    - (void)aDeprecatedProtocolMethod __deprecated;
    

    This alone should be enough for Xcode to display a deprecation warning. However, you should follow the next few steps (knowing that Xcode can be very finicky at times) to ensure the warning displays.

  2. Add a documentation comment with a deprecation warning tag. See the code example below to learn how:

    /** Describe the method here - what does it do, how does it work, etc. Very brief.
        @deprecated This delegate method is deprecated starting in version 2.0, please use otherMethodNameHere:withAnExtraParameter: instead. */
    - (void)aDeprecatedProtocolMethod __deprecated;
    
  3. Clean the project (++K) and then Build the project (+B) - just because Xcode can be funky sometimes.

I'm not 100% sure when or where this feature was introduced (maybe with SDK 7.0 and 10.9, or Xcode 5.0 / 5.0.1, or with LLVM 5.0) - but it works nonetheless.

Sam Spencer
  • 8,492
  • 12
  • 76
  • 133
4

Well, I just realised, that even Apple use __attribute__((deprecated)) at the end. And it does not work either. If I use any deprecated delegate method, e.g.

- (UITableViewCellAccessoryType)tableView:(UITableView *)tableView
     accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath

there is no warning.

So it seems like a candidate for radar.

EDIT: filed a radar, Bug ID# 11849771.

Vilém Kurz
  • 3,401
  • 2
  • 34
  • 43
3

Apple deprecated some methods in the UITableViewDelegate protocol, perhaps you'll be able to find the solution using Apple's code as example.

The relevant code of the protocol is as follows:

- (UITableViewCellAccessoryType)tableView:(UITableView *)tableView
         accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath
 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_NA,__MAC_NA,__IPHONE_2_0,__IPHONE_3_0);

As you can see, Apple uses a macro. Perhaps this is the way to go?

EDIT: As noted on the following link [1] __attribute__((deprecated)) is a GCC construct so this might not work in LLVM. I guess this is the reason Apple uses macros, so some other (or no) deprecation construct will be called when other compilers are used.

[1] How to deprecate a method in Xcode

Community
  • 1
  • 1
Wolfgang Schreurs
  • 11,779
  • 7
  • 51
  • 92
  • The macro expands to `__attribute__((availability(ios,introduced=2.0,deprecated=3.0)))`. See into `Availability.h` and `AvailabilityInternal.h` (both in `/usr/include/`) – JustSid Jul 11 '12 at 14:47
  • Yes, they speak about GCC, but __attribute__((deprecated)) actually works on Apple LLVM, except for protocols. It's confusing at the moment. – Vilém Kurz Jul 11 '12 at 15:07