Objective c 解释C预处理器代码
给定Objective c 解释C预处理器代码,objective-c,c-preprocessor,stringification,Objective C,C Preprocessor,Stringification,给定\define LOG_OBJECT(OBJECT)(NSLog(@“#OBJECT@”%@%@:%d),[OBJECT description],[NSString stringWithUTF8String:u FILE_uuuuuuuuuuuu]lastPathComponent],[uuuuuu LINE_uuuuu]);语句LOG_OBJECT(self将生成: 2014-07-18 17:43:30.041 FrogCamera[12484:2144843]self ViewCon
\define LOG_OBJECT(OBJECT)(NSLog(@“#OBJECT@”%@%@:%d),[OBJECT description],[NSString stringWithUTF8String:u FILE_uuuuuuuuuuuu]lastPathComponent],[uuuuuu LINE_uuuuu]);
语句LOG_OBJECT(self将生成:
2014-07-18 17:43:30.041 FrogCamera[12484:2144843]self
ViewController.m:20
我希望了解预处理器代码是如何工作的。我如何才能看到预处理器生成的语句
具体而言:
为什么整个#define语句被包装在()
中
#object
是否是提供的值的文本替换
为什么在#对象之前要求@“
也就是说,@“#object@%@%@:%d”
如何转换为@“self%@%@:%d”
下面是一个用法示例:
@interface ViewController ()
#define LOG_OBJECT(object) (NSLog(@"" #object @" %@ %@:%d", [object description], [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__));
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
LOG_OBJECT(self);
// = 2014-07-18 17:48:19.439 FrogCamera[12597:2151087] self <ViewController: 0x79755000> ViewController.m:20
(NSLog(@"self %@ %@:%d", [self description], [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__));
// = 2014-07-18 17:48:19.440 FrogCamera[12597:2151087] self <ViewController: 0x79755000> ViewController.m:21
}
@end
@界面视图控制器()
#定义日志对象(对象)(NSLog(@“”#对象@“%@%@:%d)”,[对象描述],[NSString STRING WITHUTF8STRING:\uuuu文件\uuuuuuuuu]lastPathComponent],\uuuuuuu行];
@结束
@实现视图控制器
-(无效)viewDidLoad{
[超级视图下载];
日志对象(自身);
//=2014-07-18 17:48:19.439 FrogCamera[12597:2151087]self-ViewController.m:20
(NSLog(@“self%@%@:%d”,[self description],[NSString stringWithUTF8String:\uuuu文件\uuuuuuuuu]最后路径组件],\uuuuu行]);
//=2014-07-18 17:48:19.440 FrogCamera[12597:2151087]self-ViewController.m:21
}
@结束
有关日志对象语句的来源,请参阅。如果要查看预处理器宏的扩展内容,请在文件打开时单击产品菜单,然后单击执行操作->预处理“ViewController.m“。这将让您看到替换了宏的扩展源的外观。有关如何使用宏的更多详细信息,请参见如果要查看预处理器宏的扩展内容,请在文件打开时单击产品菜单,然后执行操作->预处理“ViewController.m”。这将让您看到替换了宏的扩展源的外观。有关如何使用宏的更多详细信息,请参见这相当简单:
每当展开的宏可能执行意外操作时,都会使用宏中的括号。一个典型的例子是:
#define SUM(A, B) A + B
SUM(1, 1) * 3 //the expected result is 6, the real result is 1 + 1 * 3 = 4
在每个宏周围添加括号是防止此类错误的良好编程约定
#param
是一个字符串化操作符。它将参数用引号括起来-例如,参数值
被转换为“值”
字符串化操作符创建一个C字符串,它是一个字符数组(char*
)。作者想要一个NSString*
,这就是为什么他要在开头添加一个@
。请注意,@“aaa”“bbb”
相当于@“aaabb”
(此功能使我们能够在多行上拆分字符串)。然而,这不是很优雅。使用%s
会使它更简单一些
它仅转换为@““self”@“%@%@:%d”
。编译器将连续字符串视为一个字符串
这相当简单:
每当展开的宏可能执行意外操作时,都会使用宏中的括号。一个典型的例子是:
#define SUM(A, B) A + B
SUM(1, 1) * 3 //the expected result is 6, the real result is 1 + 1 * 3 = 4
在每个宏周围添加括号是防止此类错误的良好编程约定
#param
是一个字符串化操作符。它将参数用引号括起来-例如,参数值
被转换为“值”
字符串化操作符创建一个C字符串,它是一个字符数组(char*
)。作者想要一个NSString*
,这就是为什么他要在开头添加一个@
。请注意,@“aaa”“bbb”
相当于@“aaabb”
(此功能使我们能够在多行上拆分字符串)。然而,这不是很优雅。使用%s
会使它更简单一些
它仅转换为@““self”@“%@%@:%d”
。编译器将连续字符串视为一个字符串
基于C,2#
是一个运算符。4.相邻的字符串文字被连接起来。基于C,2#
是一个运算符。4.相邻的字符串文字是串联的。