English 中文(简体)
Suppressing " … is deprecated" when using respondsToSelector
原标题:

I m supporting 10.4+ by picking the most-current API at runtime:

if ([fileManager respondsToSelector:@selector(removeItemAtPath:error:)])
    [fileManager removeItemAtPath:downloadDir error:NULL];
else
    [fileManager removeFileAtPath:downloadDir handler:nil];

In this case, 10.5 and up will use removeItemAtPath:error: and 10.4 will use removeFileAtPath:handler:. Great, but I still get compiler warnings for the old methods:

warning:  removeFileAtPath:handler:  is deprecated [-Wdeprecated-declarations]

Is there a syntax of if([… respondsToSelector:@selector(…)]){ … } else { … } that hints the compiler (Clang) to not warn on that line?

If not, is there a way to tag that line to be ignored for -Wdeprecated-declarations?


After seeing some of the answers, let me clarify that confusing the compiler into not knowing what I m doing is not a valid solution.

最佳回答

I found an example in the Clang Compiler User s Manual that lets me ignore the warning:

if ([fileManager respondsToSelector:@selector(removeItemAtPath:error:)]) {
    [fileManager removeItemAtPath:downloadDir error:NULL];
} else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    [fileManager removeFileAtPath:downloadDir handler:nil];
#pragma clang diagnostic pop
}
问题回答

You could declare a separate file that is designated for calling deprecated methods and set the per-file compiler flags in Xcode to ignore -Wdeprecated-declarations. You can then define a dummy function in that file to call the deprecated methods, and thereby avoid the warnings in your real source files.

I m not sure if clang is smart enough to catch this, but if it s not, you could try using performSelector:withObject:withObject: or building and invoking an NSInvocation object.

You could just cast fileManager to an idids are able to refer to any Objective-C object, so the compiler isn t supposed to check methods which are called on one:

[(id)fileManager removeItemAtPath:downloadDir error:NULL];

shouldn t raise any warnings or errors.

Of course, this raises other problems — namely, you lose all compile-time checking for methods called on the id. So if you misspell you method name, etc, it wont be caught until that line of code is executed.

If you consider any form of "confusing" the compiler to be an invalid solution, you re probably going to have to live with the warning. (In my book, if you asking how to get rid of a warning, it s unwise to look a gift horse in the mouth and say something is invalid just because it doesn t look like you d expect.)

The answers that work at runtime involve masking the operation that s happening with dynamic dispatch so the compiler doesn t complain about the deprecated call. If you don t like that approach, you can turn off "Warn About Deprecated Functions" in your Xcode project or target settings, but that s generally a bad idea. You want to know about deprecated APIs, but in this case you want to use it without warning. There are easy and hard ways to do this, and odds are you d consider all of them "invalid" in some form, but that doesn t prevent them from being effective, even correct. ;-)

One possible way to avoid the warnings yet still select at runtime is to use objc_msgSend() directly:

objc_msgSend(fileManager, @selector(removeFileAtPath:error:), downloadDir, nil];

This is what the Objective-C runtime does under the covers anyway, and should accomplish the result you want with a minimum of fuss. You can even leave the original line commented above it for clarity. I know the documentation says, "The compiler generates calls to the messaging function. You should never call it directly in the code you write." You alone have to decide when it s okay to bend the rules.





相关问题
How to change out-of-focus text selection color in Xcode?

Okay, I ll bite. I ve got really pleasant code/window colors set up in Xcode. Ordinarily, my selection color is very visible. When I am doing a project search and iterating through the results, ...

Iphone NSTimer Issue

Hi I am new to objective c. I am trying to make an app for iphone. I have a button on my view, and the click on which the function playSound is called. This is working properly. It does plays the ...

Include a .txt file in a .h in C++?

I have a number of places where I need to re-use some template code. Many classes need these items In a .h could I do something like: #include <xxx.txt> and place all of this code in the ....

Iterating over string/strlen with umlauted characters

This is a follow-up to my previous question . I succeeded in implementing the algorithm for checking umlauted characters. The next problem comes from iterating over all characters in a string. I do ...

Xcode open two editor windows with same file

Is it possible to open the same file in two separate windows in Xcode. I can open a file in one window and the same file in the main Xcode editor window, but I wanted two separate fulltime editor ...

Forcing code signing refresh in Xcode

In our environment, we share resources across multiple projects and platforms. When building for iPhone, only a subset of those resources are needed. Since that subset is still considerable, we have ...

热门标签