Suppressing deprecation warning in Objective-C with #available - objective-c

Given the #available command in Objective-C, I was expecting that the deprecation warning would go away just like in Swift.
Example:
ABPerson *abPerson = [participant ABPersonInAddressBook:[ABAddressBook addressBook]];
'meetingAttendeeWithMeetingPlanner:andABPerson:' is deprecated: first deprecated in macOS 10.11 - use contact framework
With the #available close I can condition the use of the api framework, my guess is that this would silence the warning but it doesn't. Is this the right way to use the #available command, and if it is, is there a way to silence the warning?
if (#available(iOS 9, macOS 10.11, *)) {
}
else{
ABPerson *abPerson = [participant ABPersonInAddressBook:[ABAddressBook addressBook]];
}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
... the code using the deprecated API ...
#pragma clang diagnostic pop

#available in Objective-C is used when you want to check, if current iOS (/MacOS) version supports this API. It is called when you implement API which is supported starting by some iOS version, but not supported by older iOS.
As far as I know, you can't silent warning about deprecated API - you can only replace it with new.

Related

Ignore "Unused Entity Issue: Unused Variable" in a single file

I want to get rid of this compiler warning in just one file of my Xcode project. Is there a way to do this?
You can turn off specfic warnings in Clang using a pragma directive and the "diagnostic" keyword, like so:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-variable"
// Insert code here
#pragma clang diagnostic pop
No unused variable warnings will be produced for the code between the push and the pop.
A second option, even more targeted, is to mark a particular variable with a GCC-style attribute, specifically, "unused". Clang honors GCC's established attributes and won't issue a warning about that one variable:
__attribute__((unused))
NSString * thisStringIsJustForFun = #"It's only work if somebody makes you do it.";

Objective-C object subscripting, iOS5, and GCC

I have a library that was compiled against Apple's LLVM 4.2 compiler (Base SDK 6.1). In it there is object subscripting.
Imagine that my library has only one class with one method. That method does this:
NSLog(#"****** preTests");
NSDictionary *dictTest = #{ #1 : #1 };
NSLog(#"Initialized Dictionary");
NSArray *arrayTest = #[ #1, #2, #3 ];
NSLog(#"Initialized Array");
NSLog(#"****** arrayTest[1] = %#", arrayTest[1]); // First use of subscripting
NSLog(#"****** dictTest[#1] = %#", dictTest[#1]);
Now I create a new project and link this library in. In my application delegate, I call this method. I compile this application with the GCC LLVM 4.2 compiler. It compiles and links fine.
This application will run without error on iOS 6+. This application will crash on iOS 5 at the "First use of subscripting" (above).
2013-07-03 09:15:51.050 GCCTest[167:707] -[__NSArrayI objectAtIndexedSubscript:]: unrecognized selector sent to instance 0x381fb0
Compile it with the Apple LLVM 4.2 compiler and it will run normally.
objectAtIndexedSubscript: is a method made publicly available in iOS 6 and it is my understanding that it what the syntactic sugar of myArray[0] gets translated to.
Can someone help me understand why I see a crash with GCC and not Apple with iOS 5? I'm guessing it has to do with some macros somewhere... Could this be made not to crash with GCC without editing the code of my library?
According to the "Objective-C Feature Availability Index", NSArray subscripting requires at least LLVM Compiler 4.0.
Starting with iOS 6, NSArray has a objectAtIndexedSubscript: method. For iOS 5,
this method is supplied by the static Arclite library that is linked into the application
(see e.g. How to enable the new Objective-C object literals on iOS? and the links given in the answer).
But that is a Clang only feature, GCC does not support ARC.
So I do not see how you could use array subscripting if the main application is compiled and linked with GCC.

How to suppress the deprecation warning "dispatch_get_current_queue() is deprecated...in iOS 6.0"?

So the question is the subject question - I want to get rid of this warning which is pretty annoying.
Is there a way to make it silent?
Note: I use dispatch_get_current_queue() for debugging purposes only.
You could use the following code to suppress the warnings.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
dispatch_get_current_queue() // your deprecated calling code
#pragma clang diagnostic pop

sending messages to Class - get rid of "multiple methods named [...]" warning

I am passing a Class type as a parameter to a method, and the LLVM compiler in XCode 4.5.2 generates a warning, "multiple methods named 'foo' found", which is understandable, but undesired in this case. How do I get rid of this warning, either by disabling this type of warning, or by making changes to my code?
- (void) fooWithClass: (Class) theClass
{
[theClass aClassMethodOfThatClass];
}
more specifically, the parameter is a subclass of a certain base class, and i am sending a message which is declared in that base class.
Deactivating -Wall did not work for me, in case anybody is still interested:
After digging around in the LLVM manual, I found that the exact warning you need to ignore using Peres's method (as of Xcode 7) is:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-selector-match"
// code
#pragma GCC diagnostic pop
To disable the warning, you can check the clang manual. Like this:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wall"
[theClass aClassMethodOfThatClass];
#pragma GCC diagnostic pop

How to check if my IOS App support IOS 3+? And something about anonymous function

I'm new to IOS development, sometimes I use a function but ignore its Doc.
So, I may use some functions are only supported on IOS 4 or even IOS 5, but I want to support IOS 3+.
Does it has any way to check if my app support IOS 3+?
I don't want to check line by line, thx.
And BTW, anonymous function like void (^ funcName)(NSString *) is objective-c feature, right? So it is supported on all IOS version, right?
Change your 'Deployment Target' to 3.x to see if any methods you're using aren't supported on that version.
That however is not a substitute for testing on 3.x; so either find a 3.x device or drop support for that version. Also, blocks (the 'anonymous function' you describe) are only available on iOS 4 and above.
If you want to write different sets of code for different version targets, you can use preprocessor directives:
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 50000
... 5.x code here ...
#elif __IPHONE_OS_VERSION_MAX_ALLOWED >= 40000
... 4.x code here ...
#else
... 3.x code here ...
#endif
Try running your app on a device running 3.x
by anonymous functions do you mean blocks like:
[self performSomeBlock:^(NSString *smth) {
NSLog(#"%#", smth);
}];
or do you mean just c like definitions (its late so i forgot the legit name)
void doSomething(void *(*func)(NSString *)) {
...
}