使用Xcode 8.3.2,如果我在Objective-C文件中使用tasks:
- name: EC2 Instance
ec2:
aws_access_key: <hidden>
aws_secret_key: <hidden>
instance_type: c4.4xlarge
image: ami-221ea342
monitoring: yes
region: us-west-2
wait: yes
volumes:
- device_name: /dev/xvda
volume_type: gp2
volume_size: 80
- device_name: /dev/xvdf
volume_type: gp2
volume_size: 500
exact_count: 2
count_tag:
Component: "MyEC2"
Environment: Production
<snip>
instance_tags:
Component: "MyEC2"
Environment: Production
<snip>
并选择Product&gt;执行操作&gt;预处理“MySourceFile.m”,nil
变为nil
。我有几个问题:
((void *)0)
是语言的一部分,为什么预处理器会对它做任何事情?为什么编译步骤不直接接受nil
?nil
的整个点是空对象指针时,为什么nil
会变成((void *)0)
?为什么不对((id)0)
这样的内容进行预处理,因为像this one这样的来源定义了它?答案 0 :(得分:3)
“语言的一部分”并不一定意味着“编译器的一部分”。例如,C标准强制NULL
为宏。没有Objective-C标准,因此Objective-C实现者可以做他们想要的事情。重要的是,当您使用整个编程环境时,您可以访问表示没有对象的nil
标记。
nil
并不总是与NULL
相同:它used to be defined as just 0,然后在2007年左右它是changed to __DARWIN_NULL
,在最近的版本中它将是nullptr
在Objective-C ++模式下,__DARWIN_NULL
。 (__DARWIN_NULL
来自<sys/_types.h>
。)
Xcode对于找到“伪关键字”的定义有点讨厌。我发现对于Xcode视为关键字的宏(如nil
和NULL
),找到它们定义位置的最佳方法是重新定义它们并查看错误消息。
#define nil 0
^
foo/main.m:29:9: warning: 'nil' macro redefined [-Wmacro-redefined]
In module 'Foundation' imported from foo/main.m:9:
In module 'CoreFoundation' imported from /.../Frameworks/Foundation.framework/Headers/Foundation.h:6:
In module 'Dispatch' imported from /.../Frameworks/CoreFoundation.framework/Headers/CFStream.h:15:
In module 'os_object' imported from /.../include/dispatch/dispatch.h:66:
In module 'ObjectiveC' imported from /.../include/os/object.h:99:
/.../include/objc/objc.h:108:12: note: previous definition is here
# define nil __DARWIN_NULL
^
答案 1 :(得分:2)
nil
或NULL
都不是(Objective-)C语言本身的一部分,也就是说它们不是关键字而是库/框架中预定义的常量/宏。
这来自C标准:
值为0的整型常量表达式或类型为void *的表达式称为空指针常量。如果将空指针常量转换为指针类型,则保证将结果指针(称为空指针)与不等于指向任何对象或函数的指针进行比较。
并且通常包括强制转换以使其清楚,结果是空指针常量。对于C指针类型使用NULL
和对Objective-C对象引用类型使用nil
也是惯例,它们都扩展为空指针常量。