总结一下iOS系统的宏定义
前言
相信很多开发者也会发现,当苹果持续发布新的系统版本时,我们开发中途总会时不时出现一些告警提示如下图
这个警告说的是 frameInterval 这个属性在iOS10系统首次被废弃(Deprecated),苹果经常会随着版本的迭代废弃一些已经过时的方法或属性。然后引入一个更优秀的API,把原来的API给废弃掉。新引入的API通常意味着可以更好的发挥新硬件或操作系统的性能,或者可以使用一些在构建原有API时根本还没有的语言特性。相关链接
其实我们平时查看官方API时,也会发现很多属性和方法后面会有一个宏定义在,如下图:
那么这些系统的宏定义具体都有哪些呢?分别表示什么意思?我们平时开发怎么仿写?我做了一些总结归纳如下(有空我会定期更新):
available
如同英文意思一样,表明函数or属性等有效,手机端常用的是NS_AVAILABLE_IOS(_ios),括号里是指定有效的版本,即声明最低支持的操作系统版本。使用方式如下:
@property (nonatomic, assign) BOOL isTrue NS_AVAILABLE_IOS(11_0);//属性在iOS11.0以上才能使用
- (void)setBgColor:(UIColor *)color NS_AVAILABLE_IOS(7_0);//函数在iOS7.0以上才能使用
typedef NS_ENUM(NSInteger,GameState) {
GameStateLeisure,
GameStateLoading,
GameStatePlaying
} NS_ENUM_AVAILABLE_IOS(2_0);//此枚举在iOS2.0以上才能使用
NS_CLASS_AVAILABLE_IOS(2_0) //此类在iOS2.0以上才能使用
@interface GameManager : NSObject
- (void)rePlay NS_AVAILABLE_IOS(5_0);//此方法在iOS5.0以上才能使用
@end
也可以直接用API_AVAILABLE(...),括号里是平台名字+指定有效的最低系统版本,使用范围和上面的差不多,声明方式多了系统指定,举例如下:
API_AVAILABLE(macos(10.10))
API_AVAILABLE(macos(10.9), ios(10.0))
API_AVAILABLE(macos(10.4), ios(8.0), watchos(2.0), tvos(10.0))
unavailable
表明函数or属性无效,接口不可用,常用的有UNAVAILABLE_ATTRIBUTE亦或NS_UNAVAILABLE,如果标明了不可以用但是开发者使用该方法时,编译器会直接报错,可以用来让其他开发者只使用我们定义的根方法,示例式如下:
@interface TestModel : NSObject
//让开发者只能用我们提供的根方法实例化,防止空数据传入
- (instancetype)initWithFatherVC:(UIViewController *)chatVC uid:(int64_t)uid;
- (instancetype)init NS_UNAVAILABLE;//不让用init实例化
- (instancetype)new NS_UNAVAILABLE;//不让用new实例化
@end
deprecated
表明函数or属性被弃用,接口已经无效,可以加描述内容,需要指定可用范围,指定后如果当前开发target版本大于该方法指定的最高有效版本时,编译器会标黄警告。
常用的宏定义有
NS_DEPRECATED_IOS(_iosIntro, _iosDep, ...)括号表示(ios起始版本,ios结束版本)
NS_DEPRECATED(_macIntro, _macDep, _iosIntro, _iosDep, ...)括号表示(macos起始版本,macos结束版本,ios起始版本,ios结束版本)
示例:
//注明函数在iOS3-6可用
- (void)playToFrame:(NSInteger)frame NS_DEPRECATED_IOS(3_0,6_0);
//注明函数在mac9-11,iOS7-12可用
- (void)deprecated NS_DEPRECATED(9_0, 11_0, 7_0, 12_0);
同理,类,枚举也能废弃,宏定义基本大同小异:
//注明废弃类
NS_CLASS_DEPRECATED_IOS(2_0, 9_0, "TestView is deprecated. Use NewTestView instead")
@interface TestView : UIView
@end
//注明废弃枚举
typedef NS_ENUM(NSInteger, GameState) {
GameStateLeisure NS_ENUM_AVAILABLE_IOS(7_0) = 0,
GameStateDefault NS_ENUM_DEPRECATED_IOS(2_0, 7_0, "Use GameStateLeisure") = 0,
GameStateLoading = 1,
GameStatePlaying = 2,
}
iOS10开始提供了新的deprecated宏API_DEPRECATED和API_DEPRECATED_WITH_REPLACEMENT。前者可以注明弃用原因,后者可以注明替代接口,系统告警后直接点击修复可以替换成设定的新函数。写法如下:
//API_DEPRECATED
- (void)play API_DEPRECATED("use new_play instead", ios(7.0, API_TO_BE_DEPRECATED));
//API_DEPRECATED_WITH_REPLACEMENT
- (void)play API_DEPRECATED_WITH_REPLACEMENT("new_play", tvos(10.0, 10.4), ios(9.0, 10.0));