我正在使用gdb(在Xcode中)逐步完成一些简单的Objective-C代码,并注意到一些奇怪的东西。以下是相关摘录:
NSString *s = nil;
int x = (s == nil);
正如我所料,这两行后x
的值为1
。奇怪的是,如果我在gdb中尝试类似的东西,它不会起作用:
(gdb) print ret
$1 = (NSString *) 0x0
(gdb) print (int)(ret==nil)
$2 = 0
(gdb) print nil
$3 = {<text variable, no debug info>} 0x167d18 <nil>
似乎gdb对于nil有一些定义,而不是Objective-C使用的定义(0x0)。有人能解释一下这里发生了什么吗?
答案 0 :(得分:9)
编译代码时,nil
是一个预处理器常量,定义为__null
(用作NULL
的特殊GCC变量),0L
或0
:
<objc/objc.h>
#ifndef nil
#define nil __DARWIN_NULL /* id of Nil instance */
#endif
<sys/_types.h>
#ifdef __cplusplus
#ifdef __GNUG__
#define __DARWIN_NULL __null
#else /* ! __GNUG__ */
#ifdef __LP64__
#define __DARWIN_NULL (0L)
#else /* !__LP64__ */
#define __DARWIN_NULL 0
#endif /* __LP64__ */
#endif /* __GNUG__ */
#else /* ! __cplusplus */
#define __DARWIN_NULL ((void *)0)
#endif /* __cplusplus */
那么,gdb在运行时选择的nil
来自哪里?你可以从消息中看出gdb给出nil
是位于该地址的变量的名称:
(gdb) p nil
$1 = {<text variable, no debug info>} 0x20c49ba5da6428 <nil>
(gdb) i addr nil
Symbol "nil" is at 0x20c49ba5da6428 in a file compiled without debugging.
毫不奇怪,它的价值是0
:
(gdb) p *(long *)nil
$2 = 0
(gdb) x/xg nil
0x20c49ba5da6428 <nil>: 0x0000000000000000
这个变量来自哪里? GDB可以告诉我们:
(gdb) i shared nil
3 Foundation F - init Y Y /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation at 0x20c49ba5bb2000 (offset 0x20c49ba5bb2000)
实际上,当我们检查基金会中定义的符号时,我们会找到nil
:
$ nm -m /System/Library/Frameworks/Foundation.framework/Foundation | grep nil$
00000000001f4428 (__TEXT,__const) external _nil
答案 1 :(得分:1)
它指向内存中的地址,而不是变量内容。