1

Is there a way to test for the existence of C functions in Objective-C? I'm looking for something like "respondsToSelector," but for C functions.

More specifically, I'm trying to test for the existence of "UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque>, CGFloat scale)" in iOS.

Thanks.

RyanM
  • 5,680
  • 9
  • 45
  • 55
  • 1
    If you know that `UIGraphicsBeginImageContextWithOptions` is only in iOS 4.0 or later, you can check the iOS version the app is running on. That's a better method for stuff like this. – Stephen Furlani Jan 13 '11 at 21:47
  • I disagree, that is a worse method. You should check for the functionality you want to use instead of version checking when possible, and it's possible here. – Ken Jan 13 '11 at 21:51
  • I researched this option, but checking the version is problematic because Apple could change the naming convention on a future device... thus, causing my app to crash. After looking at other S.O. posts, I found that many recommend against checking the os version. Thoughts? – RyanM Jan 13 '11 at 21:53
  • @Ken is right. It's pretty rare that you've ever want to check the device or OS you're running on. Just check for the existence of the method/class/function. – kubi Jan 13 '11 at 21:55

3 Answers3

10
if(&UIGraphicsBeginImageContextWithOptions != NULL)
    UIGraphicsBeginImageContextWithOptions();
    else NSLog(@"No UIGraphicsBeginImageContextWithOptions function");
ughoavgfhw
  • 39,734
  • 6
  • 101
  • 123
  • [This documentation article](https://developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html#//apple_ref/doc/uid/20002378-106633-CJBGFCAC) shows `if (MyWeakLinkedFunction != NULL)`, not `if (&MyWeakLinkedFunction != NULL)`. Why did you add that ampersand? – Iulian Onofrei Nov 08 '16 at 08:47
  • @IulianOnofrei It doesn't make a difference. In C, a function gets converted to a pointer automatically if you don't do it, so the two are equivalent. – ughoavgfhw Nov 10 '16 at 00:11
  • The benefit of prefixing the function name with an ampersand is that the pointer conversion becomes explicit, rather than implicit. In Xcode, if you attempt to compare the function name without a preceding ampersand against `!= NULL`, it will warn you with the following semantic error: `Comparison of function 'UIGraphicsBeginImageContextWithOptions' not equal to a null pointer is always true`; if you do include the ampersand and prefix the function name, the function name to pointer conversion is explicit and the compiler doesn't need to generate a warning. – bluebinary Apr 03 '18 at 19:47
2

Yes, see the documentation on weak linking.

It'll work out to checking if the function pointer is NULL before calling the function.

Ken
  • 12,933
  • 4
  • 29
  • 32
  • That was very helpful. I already knew about weak linking frameworks, but didn't know that type of thing extended to functions/etc. Thanks. – RyanM Jan 13 '11 at 22:03
1

Since UIGraphicsBeginImageContextWithOptions is only present in iOS 4.0 and later, you can check the iOS target version with the __IPHONE_OS_VERSION_MAX_ALLOWED macro:

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 40000
    UIGraphicsBeginImageContextWithOptions(...);
#else
    // Function not available, fail gracefully
#endif
Adam Rosenfield
  • 390,455
  • 97
  • 512
  • 589
  • I know this is old answer, but I suspect you meant `__IPHONE_OS_VERSION_MIN_REQUIRED` rather than `__IPHONE_OS_VERSION_MAX_ALLOWED`. Just because you're using a version that supports iOS 5 doesn't mean your min target is 4.0 or greater. Obviously, even better would be runtime checking as in the accepted answer or as discussed here: http://stackoverflow.com/questions/3339722/check-iphone-ios-version – Rob Feb 25 '13 at 16:48