如何暂时禁止在nil对象上调用选择器。
实际上我得到了一个错误的访问异常,几个小时后我才知道我在使用数组时没有调用alloc-init。
我可以拥有类似的东西
prefix.h文件中的#define DISABLE_SELECTORS_ON_NIL_OBJECTS
或者某些复选框,某些位于项目设置中,或者某些异常可以禁用nil对象上的选择器,或者
我是否必须始终将代码放入if(object!= nil)?
答案 0 :(得分:2)
错误的访问异常意味着您的未初始化的对象变量不是 nil
。在Objective-C中,只有实例变量会自动归零。其他人保留该内存位置或上次使用时注册的任何值。唯一的解决方法是确保在使用变量之前对其进行初始化,即使这意味着将变量设置为nil
。
在代码上运行静态分析器。它经常可以找到这样的问题,并帮助您解决它们。
答案 1 :(得分:1)
简短回答:我不相信有任何简单的方法可以按照你建议的方式做到这一点。
答案很长:你可以在运行时抓住它......
如果您正在使用ARC,则所有Objective-C对象引用类型的变量将由运行时初始化为nil
。然而,正如Eric Skroch所暗示的那样,访问权限可能不是nil
。
作为调试辅助工具,有各种环境变量可以设置为让Objective-C运行时在代码运行时打印出大量信息,请参阅Apple的Mac OS X Debugging Magic(该文档)引用iOS版本,但它似乎是MIA)。但是,似乎没有任何内容可以将消息捕获到nil
。
如果所有其他方法都失败,请使用断点...这是objc_msgsend
(OS X)的开头:
libobjc.A.dylib`objc_msgSend:
0x7fff9774d240: testq %rdi, %rdi
0x7fff9774d243: je 0x7fff9774d270 ; objc_msgSend + 48
0x7fff9774d245: testb $0x1, %dil
0x7fff9774d249: jne 0x7fff9774d287 ; objc_msgSend + 71
0x7fff9774d24c: movq (%rdi), %r11
0x7fff9774d24f: pushq %rax
0x7fff9774d250: movq 0x10(%r11), %r10
0x7fff9774d254: movl %esi, %eax
0x7fff9774d256: andl (%r10), %eax
0x7fff9774d259: movq 0x10(%r10,%rax,8), %r11
0x7fff9774d25e: incl %eax
0x7fff9774d260: testq %r11, %r11
0x7fff9774d263: je 0x7fff9774d29b ; objc_msgSend + 91
0x7fff9774d265: cmpq (%r11), %rsi
0x7fff9774d268: jne 0x7fff9774d256 ; objc_msgSend + 22
0x7fff9774d26a: popq %rax
0x7fff9774d26b: jmpq *0x10(%r11)
0x7fff9774d26f: nop
0x7fff9774d270: movq -0x19eb41e7(%rip), %rdi ; _objc_nilReceiver
0x7fff9774d277: testq %rdi, %rdi
0x7fff9774d27a: jne 0x7fff9774d245 ; objc_msgSend + 5
0x7fff9774d27c: xorl %eax, %eax
最后一条指令是第一条命令,当它确定接收器绝对是nil
时。因此,如果您认为可能会向nil
发出意外消息,您可以在该指令上断点 - LLDB文档会告诉您如何不知道。
HTH。