开发者

How to check if not available methods are used if deployment target < base sdk?

I would like to know how yo开发者_Python百科u check that your code do not call not available methods when the deployment target is inferior to base SDK ?

It is possible to run the application on a device with the SDK equal to deployment target, but I search a way more 'automatic'. Any idea ?

Regards, Quentin


The easiest way to do this is to use the __IPHONE_OS_VERSION_MAX_ALLOWED preprocessor define.

You do this by adding

__IPHONE_OS_VERSION_MAX_ALLOWED=__IPHONE_4_2

or something similar to your "Preprocessor Macros" option in Build Settings of your target. You can look up versions available in <Availability.h>.

Unfortunately if you add this define it will cause mismatch errors with your precompiled header. So, to fix that you need to turn off the "Precompile Prefix Header" option in your build settings as well.

Once you do this you'll get a bunch of errors for classes that don't exist on your targeted SDK (for instance NSOrderedSet doesn't exist in iOS 4.2). If you're trying to go back pre-iOS 4 you'll probably get so many errors that the compiler bails--I don't know of a workaround for this. In any case, ignore the errors about missing classes in the UIKit headers, and go to the bottom of the error list; there you should find an error for each time you use a method or class that isn't included in the SDK pointed to by __IPHONE_OS_VERSION_MAX_ALLOWED. Make sure each of these methods is enclosed in an

if( [targetObject respondsToSelector:@selector(thePossiblyMissingSelector:)]

and you should be safe. Classes that may be missing should be tested as well

if ([NSOrderedSet class] != nil)

These settings aren't something you want to accidentally forget to flip back however. To make this an automatic option for testing, do the following:

  1. Create a new build configuration called something like "Old SDK Testing".
  2. Define __IPHONE_OS_VERSION_MAX_ALLOWED and the precompiled head option only for this configuration (hit the disclosure arrow beside each line in Build Settings to access per configuration settings).
  3. Duplicate your current Scheme and set its name to something like "Old SDK Check".
  4. Set the Build Configuration of the Run item in this new scheme to the build configuration you created in step 1.
  5. Select the new Scheme and build.

Notes:

  • I make no guarantee that this will catch any/all of your issues.
  • Anything outside of UIKit will not be caught by this check.
  • This is not a substitute for testing your code on the versions of iOS you plan to support.


use NSClassFromString();

Class cls = NSClassFromString(@"YourClass");
if (cls == nil)

is this you are looking for?


  1. best way to do that which i found: compile code with old SDK :) link which can help

  2. I think this question is releated with next

  3. I belive that someday Apple allow to compile project for old SDK by simple defining #define __IPHONE_OS_VERSION_MAX_ALLOWED __IPHONE_3_0

  4. upd: I found solution here

4.3 5.0 and 5.1 SDK just fail to compile after trying to redefine this macro


Are you looking for something like - (BOOL)respondsToSelector:(SEL)aSelector


If you have an instance of a class, you can use the following to see if it understands the method you want to call:

if ([mipmapBrowserView respondsToSelector:@selector(setBackgroundColor:)]) {
    // set the background layer since IKImageView supports it
}

Here, mipmapBrowserView is an instance of IKImageView, which was first introduced in Mac OS X 10.5. The setBackgroundColor: method of IKImageView was only added in 10.6, however, so I need to check before I call it. This allows me to build against the 10.6 SDK, and take advantage of the new features, yet still support OS X 10.5 as well. While this example involves OS X rather than iOS, the same method (pun intended?) works in iOS as well.

Note that things are slightly different when you are subclassing a class, and you want to know whether the superclass responds to a certain selector:

"You cannot test whether an object inherits a method from its superclass by sending respondsToSelector: to the object using the super keyword. This method will still be testing the object as a whole, not just the superclass’s implementation. Therefore, sending respondsToSelector: to super is equivalent to sending it to self. Instead, you must invoke the NSObject class method instancesRespondToSelector: directly on the object’s superclass...."

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜