从 Apple API 中,能学习到很多关于 API 定义方面的知识。这也能帮助我们在平时的开发中,更为规范的编写代码。本文是关于通知的定义。
环境信息
Mac OS X 10.11.6
Xcode 8.0
iOS 10.0
在 NSDate 的头文件中,能看到如下定义:
FOUNDATION_EXPORT NSNotificationName const NSSystemClockDidChangeNotification NS_AVAILABLE(10_6, 4_0);
FOUNDATION_EXPORT
FOUNDATION_EXPORT 即 FOUNDATION_EXTERN 即 extern,用于告知编译器该变量或函数可在本模块或其他模块中使用。关于 Cocoa 框架中,FOUNDATION_EXTERN 的定义为:
// 如果是 C++,如下代码采用 C 编译器
#if defined(__cplusplus)
#define FOUNDATION_EXTERN extern "C"
#else
#define FOUNDATION_EXTERN extern
#endif
NSNotificationName
typedef NSString *NSNotificationName NS_EXTENSIBLE_STRING_ENUM;
NSNotificationName 即 NSString *,不过这样看着更为直观,所以,在 NSNotification 中,所有有关通知名称的,都用的 NSNotificationName 作为参数类型。
NS_EXTENSIBLE_STRING_ENUM 则是为了适配 Swift。
NS_AVAILABLE
API 可用版本。
#define NS_AVAILABLE(_mac, _ios) CF_AVAILABLE(_mac, _ios)
在 Mac 10.6 以上,iOS 4.0 以上可用。
定义
所以通知的定义方式为:
// .h
FOUNDATION_EXPORT NSNotificationName const LoginNotification;
// .m
NSNotificationName const LoginNotification = @"LoginNotification";
除此之外,也有人使用 #define 来定义通知:
#define LOGIN_NOTIFICATION @"LoginNotification"
作为宏定义,仅做替换,所以使用的时候,依然是 @"LoginNotification" 字符串,对比需要使用 isEqualToString。而使用 FOUNDATION_EXPORT NSNotificationName const 方式定义,则是直接比较地址,效率比 #define 要高出许多。