为什么objective-c没有API可用性检查?
Swift 2有API 当使用对您的应用程序来说太新的API时,编译器会给您一个错误 最小目标操作系统 为什么objective-c编译器不能做同样的事情为什么objective-c没有API可用性检查?,objective-c,llvm-clang,Objective C,Llvm Clang,Swift 2有API 当使用对您的应用程序来说太新的API时,编译器会给您一个错误 最小目标操作系统 为什么objective-c编译器不能做同样的事情 我在谷歌上搜索了objective c API可用性检查,只得到了swift 2的结果,所以我假设objective c的编译器不能这样做。当然,objective-c代码中会出现错误。但是,如果您使用为Swift定义的术语,您将无法在google中找到Objective-C的结果,因为如果您搜索德语单词,您将无法在google中找到kisu
我在谷歌上搜索了objective c API可用性检查,只得到了swift 2的结果,所以我假设objective c的编译器不能这样做。当然,objective-c代码中会出现错误。但是,如果您使用为Swift定义的术语,您将无法在google中找到Objective-C的结果,因为如果您搜索德语单词,您将无法在google中找到kisuaheli网站。;-) 将Objective-C代码与太旧的SDK链接时会出现错误。这仅仅是因为所使用的方法、类或$which没有在该SDK的头中定义。当然,也是这样 这就是苹果公司典型的Swift营销:由于Swift的无能力,他们必须扩展语言才能获得一些东西,这在Objective-C中非常容易。他们没有澄清这是Swift的糟糕表现的结果,而是告诉你这是Swift的一个重要特征。这就像割断你的手指,然后说:“我们有伟大的石膏功能!!!!!!!”你只需要等待几天,然后一个问题出现了:“为什么Objective-C没有伟大的石膏功能?”简单的回答是:它不会割断你的手指 问题不在于产生错误。问题是所有版本都有一个源代码,因此您可以简单地更改SDK版本并获取新代码(或错误)。为了便于维护,您需要它 在Objective-C中,您只需使用以下答案: 或者你也可以在运行时这样做,正如Q的注释中所提到的。(但这本质上是问题的不同解决方案,因为它是一种动态的方法,而不是Swift中必须使用的静态方法。) 在Swift中具有语言功能的原因是Swift没有预处理器,因此Objective-C解决方案在Swift中不起作用。因此,条件代码在Swift中是不可能的,他们必须添加Plast,呃,语言功能。警告(Swift使其成为错误)已经多年没有在Clang编译器中实现,但它不是固有的Objective-C限制(尽管由于其动态特性,您无法捕获所有情况),也不是快速的术语 苹果的宏(例如,
NS\u CLASS\u AVAILABLE
)和源属性(\uuu attribute\uuuuuuuuuu((可见性(…)))
,\uuuuu attribute\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu((可用性(…)))
)已经存在多年,它们在苹果的SDK中被广泛使用。宏在Foundation
的NSObjCRuntime.h
和Availability.h
/AvailabilityMacros.h
系统头中定义,编译器可以(并且确实)读取宏
2015年初,向Clang的master
分支发出的-Wpartial availability
警告,但直到(包括)Xcode 7.2,该提交/警告才进入苹果的Clang版本。在Xcode 7.2中将警告标志添加到项目时,您将获得一个未知警告选项
日志,但该标志在Xcode 7.3中可用。当前没有预定义的设置,但您可以将该标志添加到“生成设置”下的“其他警告标志”
还有其他工具使用LLVM库来检测部分可用的API,例如。在我的毕业论文中,我开发了一个直接集成到Xcode的工具,它基于对Clang编译器的修改。代码仍然是,但是我没有跟上一般的Clang开发,所以除了用于学习之外,它没有多大用处。然而,“官方”代码(如上链接)更干净、更好
编辑:从Xcode 9开始,可用性检查也适用于Objective-C(和C)。不使用上述警告标志(不支持临时/本地提升部署目标,因此会导致大量误报),而是使用
-Wunguarded availability
,和if(@available(iOS 11,*){…}
检查并提升部署目标以获取以下代码块。默认情况下,它是关闭的,但默认情况下,Wunguarded availability new将打开,并开始检查iOS/tvOS 11、watchOS 4和High Sierra之外的任何内容。有关这方面的更多详细信息,请参见,目前需要使用开发人员帐户登录。目标C没有可用性检查作为语言的一部分,因为通过目标C预处理器可以获得相同的结果。
这是C派生语言中的“传统”方法
想知道是否在调试模式下编译
#ifdef DEBUG
// code which will be inserted only if compiled in debug mode
#endif
要在编译时检查最低版本吗?
在iOS中使用Availability.h头,在Mac OS X中使用类似的头
此文件位于/usr/include目录中
只需测试预处理器允许的IPHONE操作系统版本,例如:
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert) categories:nil]];
}else{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert)];
}
#else
[[UIApplication sharedApplication] registerUserNotificationSettings: (UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert)];
#endif
由于Swift没有预处理器,他们不得不发明一种在语言本身中进行此类检查的方法
如果要在运行时检查方法的可用性,请注意,适当的方法是使用方法respondsToSelector:,或InstanceRespondsToSelector:(后者在类级别)
您通常希望将这两种方法结合起来,即编译时条件编译和运行时检查
目标C方法在场验证,例如在班级层面:
if ([UIImagePickerController instancesRespondToSelector:
@selector (availableCaptureModesForCameraDevice:)]) {
// Method is available for use.
// Your code can check if video capture is available and,
// if it is, offer that option.
} else {
// Method is not available.
// Alternate code to use only still image capture.
}
如果您想在运行时测试C函数是否存在,则更简单:如果存在,则函数本身不为null
不能在两种语言中使用相同的方法。Xcode 9.0将运行时可用性检查语法从Swift引入Objective-C:
if (@available(macOS 10.9, *))
{
// call 10.9+ API
}
else
{
// fallback code
}
这完全是w