問題描述
如何避免編譯iOS 4.0提供的常量,並內置到iOS 3.1的設備中 (How to avoid compiling the constant which is provided in iOS 4.0, and build into the device with iOS 3.1)
I have been tried the following two kinds of codes.
Run time:
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 4.0) {
CFReadStreamSetProperty(theReadStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
CFWriteStreamSetProperty(theWriteStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
}
Compile time:
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0 {
CFReadStreamSetProperty(theReadStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
CFWriteStreamSetProperty(theWriteStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
}
kCFStreamNetworkServiceType
and kCFStreamNetworkServiceTypeVoIP
are the constants provided in iOS 4.0. However, I need to build the above codes into the device with iOS 3.1 due to some reasons. If I build the above codes into the device with iOS 3.1, it will crash when I open the application. Are there any ways to solve the problem?
參考解法
方法 1:
I agree with Apurv that you should set the Deployment Target in your Xcode build settings, to iOS 3.1, and built with the latest Base SDK. But, I don't recommend that test for the operating system version.
OS versions are not floating point numbers. "3.1.3"
is a valid OS version, but it is not a floating point number. Also, comparison of floating point numbers is never really a good idea.
Instead, use the macros from this other Stack Overflow answer
<pre class="lang-objc prettyprint-override">if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"4.0")) { CFReadStreamSetProperty(theReadStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP); CFWriteStreamSetProperty(theWriteStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP); }
</pre>
Edit: As an example of why this is necessary, consider the code:
NSString* osVersion = @"3.1.3";
float x = [osVersion floatValue];
NSLog(@"OS version = %lf", x);
if (x >= 3.1) {
NSLog(@"OS >= 3.1");
} else if (x < 3.1) {
NSLog(@"OS < 3.1");
}
Running this on an iPhone 5.0 simulator produces the following output, which is obviously not what you want:
2012-07-31 17:56:38.155 HelloWorld[5856:f803] OS version = 3.100000
2012-07-31 17:56:41.257 HelloWorld[5856:f803] OS < 3.1
If you inspect the value of x
in the debugger, I see it as 3.0999999
, which triggers the incorrect comparison result.
方法 2:
You should build your application with latest SDK and provide the deployment target to iOS 3.1.
If you are putting the below check, then it should not get crash.
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 4.0) {
CFReadStreamSetProperty(theReadStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
CFWriteStreamSetProperty(theWriteStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
}
(by Chih-Shu Shih、Nate、Apurv)