我有一个包含两个目标的代码,这两个目标使用特定于iOS 4的功能,其他目标则与3.0 +兼容。
我想对代码进行最终修订,看看是否一切正常。换句话说,看看在编译iOS 3.x目标时是否没有为iOS4调用的函数。
有没有办法在编译期间列出任何不属于目标所需版本的被调用函数?
提前感谢。
答案 0 :(得分:1)
1)将编译器警告一直向上转动
2)将警告视为错误
3)将基本/目标SDK更改为您将支持的最早版本
4)干净
5)构建
隐式函数和未声明的选择器之类的东西现在应该生成错误。
为避免错误发生,请为您需要的函数或objc方法创建一个shim静态库。这个填充程序将实现代码的两种变体,并最终将针对最新的标头构建。它将包含条件运行时检查。对于objc类方法,您可以伪造,使用类别并使用生成任何警告的类别实现。
说明使用两个版本的代码:
/*
illustration:
- sortByCoordinates: was added in OS 4, but we need to implement or approximate it for our projects targeting OS 3 (or throw out an alert in some cases)
- as long as you have to support OS 3 and build against the SDKs from time to time, the compiler will produce errors or warnings when a selector has not been declared, or if an object may not respond to a selector (assuming you have directed the compiler to inform you of this)
- so we put our conditionals/runtime checks in a library here, and update our calls from sortByCoordinates: to mon_sortByCoordinates:
*/
- (void)mon_sortByCoordinates:(EECoordinate*)coordinates
{
/* MONLib_OSVersion_4_0 implies some constant, indicating OS 4 */
/* MONLibGetCurrentRuntimeVersion() is a call we make at runtime which returns the OS version, such as MONLib_OSVersion_4_0 or MONLib_OSVersion_3_2 */
if (MONLib_OSVersion_4_0 <= MONLibGetCurrentRuntimeVersion()) {
/* they are using OS 4 (or greater) - call the OS version */
[self sortByCoordinates:coordinates];
}
else {
/*
%%%%%% < else implement our approximation here >
*/
}
}
最后,由于objc的动态特性以及objc程序的编写方式,编译器无法为您捕获所有内容。有时它会更加冗长。简单的例子:
@interface MONBox
/* added in version 4 */
- (NSUInteger)count;
@end
NSUInteger beispiel() {
if (0) {
/* less safe -- the compiler will not flag this */
/* if [myNSArrayInstace objectAtIndex:0] is a MONBox then this will go undetected since the selector count may be matched to -[NSArray count] */
return [[myNSArrayInstaceOfMONBoxObjects objectAtIndex:0] count];
}
else {
/* more safe -- the compiler will flag this */
MONBox * box = [myNSArrayInstaceOfMONBoxObjects objectAtIndex:0];
return [box count];
}
}
答案 1 :(得分:0)
据我所知,我认为没有一种自动化方法可以做到这一点。为此目的,我保留了一个旧的第一代iPhone - 我将在设备上运行应用程序,看看崩溃了什么。不太理想,但适用于较小的应用程序。