OCUDL 是一个将用户定义字面量引入 Objective-C 的实验。字面量是一种简短的表示方式,用于创建某个类型的值。例如,25ul
创建了一个无符号长整型值 25,而 @"hello"
创建了一个 NSString 值 hello。用户定义字面量为我们自己的类型带来了这种简短性和表达力。
字面量通常直接嵌入到编译器中。然而,OCUDL 并没有扩展编译器;它只是利用了 Objective-C 运行时中已有的内容。您可以在 OCUDL In Depth 中了解更多关于 OCUDL 内部机制的信息。
OCUDL 源代码 在 GitHub 上可用,遵循 MIT 许可证。文档位于 CocoaDocs。欢迎提交拉取请求、报告错误和问题。
OCUDL 使用前缀或后缀定义字面量。这里,我们定义了一个使用 # 前缀的 UIColor 字面量。
// Creates a UIColor
myView.backgroundColor = $(#FE22AA);
下划线 $ 告诉 OCUDL 将此值解释为用户定义的字面量。如果用户定义字面量直接烘焙到语言中,就不需要下划线 $。
在“有用字面量”部分探索 UIKit 和 Foundation 类型的字面量示例。
OCUDL 是一个实验,可能不适合您的项目。请阅读 OCUDL In Depth 了解幕后发生的情况。请注意:OCUDL 已更新为不再依赖于方法交换。
您可以通过 CocoaPods 获取 OCUDL。您可以 [了解更多] CocoaPods 的依赖项管理信息,但我们只介绍基础知识。
安装 CocoaPods
gem install cocoapods
pod setup
在项目目录中创建一个 Podfile
。添加以下几行
platform :ios
pod 'OCUDL'
然后安装 Podfile
pod install
如果您还没有创建 workspace,CocoaPods 会为您创建一个。您将需要通过 workspace 文件在 XCode 中打开代码,而不是 .xcodeproj
文件。
现在,项目已准备好开始使用 OCUDL。通过导入头开始
#import <OCUDL/OCUDL.h>
要为您的类创建字面量,首先实现 OCUDLClass
协议。
@interface YourClass : NSObject <OCUDLClass>
然后,为您的类注册一个字面量前缀或后缀。
@implementation YourClass
+ (void)load
{
[[OCUDLManager defaultManager] registerSuffix:@"your-suffix" forClass:[YourClass class]];
}
@end
最后,实现字面量初始化器。
- (id)initWithLiteral:(NSString*)literal suffix:(NSString*)suffix
{
if (self = [super init]) {
// ...
}
return self;
}
现在,在任何项目的位置都可以使用您的字面量。
YourClass *foo = $(555your-suffix);
有时您可能想为非您所写的类添加字面量。只需使用 OCUDL 对块的支持,而不是使用分类。
[[OCUDLManager defaultManager] registerPrefix:@"#" forBlock:^id(NSString *literal, NSString *prefix) {
// return a new instance of some class
}];
OCUDL 包含了一组针对 UIKit 和 Foundation 类型的实用内置字面量。
#import <OCUDL/OCUDLBuiltins.h>
// ...
[OCUDLBuiltins use];
在您使用 [OCUDLBuiltins use]
之后,您可以在代码中的任何位置利用所有内置字面量。
NSNull *n = $(null);
NSURL *url = $(http:www.apple.com);
NSURL *url2 = $(https:www.gmail.com);
NSUUID *uuid = $(68753A44-4D6F-1226-9C60-0050E4C00067uuid);
UIColor *color = $(#FE22AA);
UIColor *color2 = $(#FFF);
UIColor *color3 = $(#yellow);
UIImage *img = $(pic.img);
UINib *nib = $(MyNib.xib);
UIStoryboard *board = $(MyBoard.storyboard);