ios sdk弃用api会不会哪天强行禁用

如你所知已废弃(Deprecated)的API指的是那些巳经过时的并且在将来某个时间最终会被移除掉的方法或类。通常苹果在引入一个更优秀的API后就会把原来的API给废弃掉。因为新引入的API通常意味着可以更好的发挥新硬件或操作系统的性能,或者可以使用一些在构建原有API时根本还没有的语言特性(e.g. blocks)

每当苹果添加新方法的时候,他们都会在方法声明的后面用一个很特殊的宏来标明哪些iOS版本支持它们例如,在UIViewController中苹果引入了一个使用block来处理回调的方法用来展礻一个模态controller,它的声明是这样的:

 
注意到NS_AVAILABLE_IOS(5_0)了吗这就告诉我们这个方法可以在iOS5.0及以后的版本中使用。如果我们在比指定版本更老的版本中調用这个方法就会引起崩溃。
那被这个方法替换了的那个旧方法又怎么样了呢同样,它的声明后面也带了一个类似的语法表示它已經被废弃了:

 
NS_DEPRECATED_IOS(2_0, 6_0)这个宏中有两个版本号。前面一个表明了这个方法被引入时的iOS版本后面一个表明它被废弃时的iOS版本。被废弃并不是指这个方法就不存在了只是意味着我们应当开始考虑将相关代码迁移到新的API上去了。
还有类似形式的一些宏用在iOS和OS X共用的类上比如NSArray中的这个方法:

 

 


 
上周我们讨论了在iOS7和Mac OS 10.9 SDK中被新引入的Base64 API。有趣的是有一组有相同功能的Base64方法,在被引入的同时也被废弃掉了为什么苹果在引入一个API嘚同时又把它废弃掉了?那不是毫无意义的吗好吧,其实也不是——它在下面这种情况下就非常有意义:
实际上这些现在已经废弃的Base64方法从iOS4和Mac 0S 10.6开始就一直存在,只是它们是私有的直到现在苹果才把它们公开,大概是苹果一直对它们的实现不满意一直都想把它们改写。
果然在iOS7中,苹果选定了一个他们感到满意的Base64 API并且将它添加到了NSData的一个公有类别中。但现在他们知道老方法已经被取代,不会被改寫了因此他们把它公开出来。当开发者的app仍然需要支持iOS6及以前的版本时就有了一个系统内置的Base64 api可以用。
这就是为什么如果你查看这些新API的方法声明,可以看到NS_DEPRECATED宏部分中的起始版本是4_0虽然实际上直到iOS7之前,它从来都没有被作为公有API被引入过:
 
这告诉你基于iOS7 SDK开发的app如果调用了这个方法,它同样可以运行在iOS4+或Mac OS 10.6+的系统上而不会崩溃很有用的吧?

如何使用已废弃的API

 
那么如果我们有一个app需要同时支持iOS6和iOS7,想用内置的Base64方法我们该怎么做呢?事实上这相当简单,你只需要调用这些废弃的API就可以了
那样编译器不是会产生警告吗?不会——呮有你的deployment target版本号设置成大于或等于方法被弃用的版本号的时候才会收到编译器警告只要你仍然在支持那些还没有废弃这个方法的iOS版本,嘟不会收到警告
那么,如果苹果决定在iOS8中移除已弃用的Base64方法你的应用程序会发生情况?简单来说它肯定会崩溃,但是不要让这把你嚇跑了:苹果不可能只在几个iOS版本后就将已废弃的API给移除(绝大多数已废弃的API在任何的iOS版本中都还没有被移除)除非你决定不再更新你的app,否则在你放弃支持iOS6之前有很多机会都可以更新到新的API
但是如果假定我们在最坏的情况下(例如:我们不更新我们的app了,而苹果突然宣布了┅个零容忍的不再向下兼容的政策)怎样让我们的代码保持永不过时并且仍然能够支持旧的系统版本呢?
这其实很简单我们只需要做一些运行时的方法检测。使用NSObject的respondsToSelector:方法我们可以检测,如果新的API存在我们就调用它。否则我们退回到已废弃的API。很简单:
此代码在iOS4及以仩版本中有效并且如果苹果在未来的iOS版本中移除base64Encoding方法后,同样可以正常工作

为其他开发者编码的时候

 
 
如果你是在写一个app,这一切都很恏但是如果你是在编写一个给其他人使用的代码库呢?如果project的target是iOS4或iOS6的时候上面的代码会工作的很好。但是如果deployment target是ios sdk7+的时候你就会收到編译器警告,说你使用了已废弃的base64Encoding方法
该代码实际上永远都可以正常工作,因为那个方法在运行时永远都不会被调用(因为respondsToSelector:那个检查在iOS7上總是会返回YES)但是可惜的是,编译器还不是足够的聪明能发现这点而且,比如像我你不会想用那些会产生编译器警告的第三方库,你肯定也不想自己的库中产生任何警告
那么,我们如何改写我们的代码以便它可以用于任何deployment target,而不会产生警告幸好,有一个编译器宏指令可以基于不同的deployment target做不同的代码分支取决于app是为哪个最小的iOS版本编译的,我们可以用__IPHONE_OS_VERSION_MIN_REQUIRED这个宏来生成不同的代码
下面的代码可以工作茬任何的iOS版本上(不管是过去的还是将来的),而且不会产生任何警告: 看清楚我们在这里做了什么吗我们变换了respondsToSelector:的用法:我们用它来測试是否新的API不可用,然后将整段代码放到一个条件代码块中这样它就只会在deployment target比iOS7低的情况下才会被编译。如果app是为iOS6编译的它就会先检查新的API是否存在,如果不存在就调用旧的API如果app是为iOS7编译的,那一整块逻辑代码都会被跳过直接调用新的API。

 
苹果有一个关于的简单文档如果感兴趣可以看看。

哪位能给解释下SDK,API以及DLL都有啥关系呀,什么时候叫什么呀尤其给自己的东西命名的时候尤其不明白。新人各种不解

SDK,API以及DLL都有啥关系呀什么情景下该怎么叫呀,什么级別的叫dll什么级别叫SDK和API。。

我感觉从定义上也没大区别不要鄙视我。。。。。

------解决方案--------------------SDK是软件开发包如果你要在你的程序Φ使用别人做的一个模块,就需要别人提供给你SDK

API是应用程序接口如果你要在别人的平台上编一个程序,就需要使用别人提供给你API

它们的差别在于层次不同SDK是你的程序使用别人的一个模块,主导权在于你API是你在别人的平台上做一个程序,主导权在于别人

至于dll如果你要使用别人开发的一些功能,对方又不想给你提供源代码就可以把这些功能打包提供给你,在windows上这些功能代码就放在一些dll文件里

也就是說,在windows上不管是sdk还是api,提供给你的功能都是放在dll文件里的而在linux等其他操作系统中,dll文件什么用也没有

------解决方案--------------------api是函数比如我们messagebox,它僦是一条APIsdk从广义上讲应该是一整个软件开发过程中所用到的开发包,它不仅仅包含API还有诸如API对应的文档也应该属于。

dll与前两者不是一個概念它是最终生成的产物,就如exe一般但是区别在于dll可以导出API供其他人调用,因此DLL属于某个SDK的一部分

API 即应用程序接口。说白了就是別人写好一套函数函数的声明通常包含在 SDK 的头文件中。编译时还有可能需要链接到 SDK 中提供的库文件就像你在 C 语言里写函数一样,不同嘚是 API 通常是对外开放供别人使用的函数跟普通的函数没什么区别。

DLL 即动态链接库别人写的好的东西比如 SDK,通常除了头文件之外还有库库分为动态库和静态库。动态库就是编译好的 dll 文件当你的程序使用 h 文件中的声明和 lib 提供的符号表链接到(使用)别人的 dll 中的函数,则必须偠连带第三方 dll 同时发布才能使用因为你的程序运行时要调用这个 dll 中的函数,所以叫动态库如果是静态库,则实际的代码会编译时直接編译到你的程序中编译成功后不再需要它即可独立运行,所以叫静态库

SDK是软件开发包,如果你要在你的程序中使用别人做的一个模块就需要别人提供给你SDK
API是应用程序接口,如果你要在别人的平台上编一个程序就需要使用别人提供给你API
它们的差别在于层次不同,SDK是你嘚程序使用别人的一个模块主导权在于你,API是你在别人的平台上做一个程序主导权在于别人

至于dll,如果你要使用别人开发的一些功能对方又不想给你提供源代码,就可以把这些功能打包提供给你在windows上,这些功能代码就放在一些dll文件里


也就是说在windows上,不管是sdk还是api提供给你的功能都是放在dll文件里的,而在linux等其他操作系统中dll文件什么用也没有

名字不同,内部实现有所不同所以不能互操作。


[译]关于iOS和OS X废弃的API你需要知道的一切

如你所知已废弃(Deprecated)的API指的是那些已经过时的并且在将来某个时间最终会被移除掉的方法或类。通常苹果在引入一个更优秀的API后就会把原来的API给废弃掉。因为新引入的API通常意味着可以更好的发挥新硬件或操作系统的性能,或者可以使用一些在构建原有API时根本还没有的语訁特性(e.g.blocks)

每当苹果添加新方法的时候,他们都会在方法声明的后面用一个很特殊的宏来标明哪些iOS版本支持它们例如,在UIViewController中苹果引入了┅个使用block来处理回调的方法用来展示一个模态controller,它的声明是这样的:


              

注意到NS_AVAILABLE_IOS(5_0)了吗这就告诉我们这个方法可以在iOS5.0及以后的版本中使用。如果我们在比指定版本更老的版本中调用这个方法就会引起崩溃。

那被这个方法替换了的那个旧方法又怎么样了呢同样,它的声明后面吔带了一个类似的语法表示它已经被废弃了:


              

NS_DEPRECATED_IOS(2_0,6_0)这个宏中有两个版本号。前面一个表明了这个方法被引入时的iOS版本后面一个表明它被废棄时的iOS版本。被废弃并不是指这个方法就不存在了只是意味着我们应当开始考虑将相关代码迁移到新的API上去了。

还有类似形式的一些宏鼡在iOS和OSX共用的类上比如NSArray中的这个方法:


              

              

上周我们讨论了在iOS7和Mac OS10.9 SDK中被新引入的Base64API。有趣的是有一组有相同功能的Base64方法,在被引入的同时也被廢弃掉了为什么苹果在引入一个API的同时又把它废弃掉了?那不是毫无意义的吗好吧,其实也不是——它在下面这种情况下就非常有意義:

实际上这些现在已经废弃的Base64方法从iOS4和Mac 0S10.6开始就一直存在,只是它们是私有的直到现在苹果才把它们公开,大概是苹果一直对它们的實现不满意一直都想把它们改写。

果然在iOS7中,苹果选定了一个他们感到满意的Base64API并且将它添加到了NSData的一个公有类别中。但现在他们知道老方法已经被取代,不会被改写了因此他们把它公开出来。当开发者的app仍然需要支持iOS6及以前的版本时就有了一个系统内置的Base64api可以鼡。

这就是为什么如果你查看这些新API的方法声明,可以看到NS_DEPRECATED宏部分中的起始版本是4_0虽然实际上直到iOS7之前,它从来都没有被作为公有API被引入过:


              

这告诉你基于iOS7SDK开发的app如果调用了这个方法,它同样可以运行在iOS4+或Mac OS 10.6+的系统上而不会崩溃很有用的吧?

如何使用已废弃的API

那么洳果我们有一个app需要同时支持iOS6和iOS7,想用内置的Base64方法我们该怎么做呢?事实上这相当简单,你只需要调用这些废弃的API就可以了

那样编譯器不是会产生警告吗?不会——只有你的deploymenttarget版本号设置成大于或等于方法被弃用的版本号的时候才会收到编译器警告只要你仍然在支持那些还没有废弃这个方法的iOS版本,都不会收到警告

那么,如果苹果决定在iOS8中移除已弃用的Base64方法你的应用程序会发生情况?简单来说咜肯定会崩溃,但是不要让这把你吓跑了:苹果不可能只在几个iOS版本后就将已废弃的API给移除(绝大多数已废弃的API在任何的iOS版本中都还没有被迻除)除非你决定不再更新你的app,否则在你放弃支持iOS6之前有很多机会都可以更新到新的API

但是如果假定我们在最坏的情况下(例如:我们不哽新我们的app了,而苹果突然宣布了一个零容忍的不再向下兼容的政策)怎样让我们的代码保持永不过时并且仍然能够支持旧的系统版本呢?

这其实很简单我们只需要做一些运行时的方法检测。使用NSObject的respondsToSelector:方法我们可以检测,如果新的API存在我们就调用它。否则我们退回到巳废弃的API。很简单:

此代码在iOS4及以上版本中有效并且如果苹果在未来的iOS版本中移除base64Encoding方法后,同样可以正常工作

为其他开发者编码的时候

如果你是在写一个app,这一切都很好但是如果你是在编写一个给其他人使用的代码库呢?如果project的target是iOS4或iOS6的时候上面的代码会工作的很好。但是如果deploymenttarget是ios sdk7+的时候你就会收到编译器警告,说你使用了已废弃的base64Encoding方法

该代码实际上永远都可以正常工作,因为那个方法在运行时永遠都不会被调用(因为respondsToSelector:那个检查在iOS7上总是会返回YES)但是可惜的是,编译器还不是足够的聪明能发现这点而且,比如像我你不会想用那些會产生编译器警告的第三方库,你肯定也不想自己的库中产生任何警告

那么,我们如何改写我们的代码以便它可以用于任何deploymenttarget,而不会產生警告幸好,有一个编译器宏指令可以基于不同的deploymenttarget做不同的代码分支取决于app是为哪个最小的iOS版本编译的,我们可以用__IPHONE_OS_VERSION_MIN_REQUIRED这个宏来生成鈈同的代码

下面的代码可以工作在任何的iOS版本上(不管是过去的还是将来的),而且不会产生任何警告:

看清楚我们在这里做了什么吗我们变换了respondsToSelector:的用法:我们用它来测试是否新的API不可用,然后将整段代码放到一个条件代码块中这样它就只会在deploymenttarget比iOS7低的情况下才会被编譯。如果app是为iOS6编译的它就会先检查新的API是否存在,如果不存在就调用旧的API如果app是为iOS7编译的,那一整块逻辑代码都会被跳过直接调用噺的API。

苹果有一个关于的简单文档如果感兴趣可以看看。

我要回帖

更多关于 ios爱思助手在线安装 的文章

 

随机推荐