为什么它是"exc_bad_access"而不是"运行时"或"编​​译时"错误?

23 memory xcode exc-bad-access objective-c ios

ScreenShot:xCode 5.1的运行模式

为什么它是一个exc_bad_access而不是一个run-timecompile-time错误?

我写错了"@age"而不是@"age",它激起了我的好奇心.

我所理解的exc_bad_access:Bad-Access是由一个指针(好的引用)引起的,该指针dereferenced是一个尚未分配或解除分配或未经授权访问(const或某事)的内存位置.

但在这种情况下,我只是将数据写入内存,语法与NS Objective-c格式不匹配.因此它应该是运行时错误而不是Bad-Access.

我在哪里错过了这个概念?

ala*_*air 24

获得EXC_BAD_ACCESS的原因是该-initWithObjects:方法期望其所有参数都是有效的Objective-C对象.每个Objective-C对象都以一个小标题开头; 这曾经是一个简单的指针,称为isa它的类对象(它不一定非常简单,现在你不应该嘲笑自己;如果需要你可以使用Objective-C运行时API ).

你在这里没有得到编译器错误的原因是在C/C++/Objective-C中没有办法为"varargs"方法或函数指定正确的类型.因此,编译器允许您传递任何类型的参数,假设您知道自己在做什么.

无论如何,在实现过程中-initWithObjects:,它会尝试向-retain你传入的每个对象发送一条消息.当它这样做时,它会尝试取消引用isa指针.对于C字符串,这意味着它将把字符串的前四个或八个字节视为指针.这不太可能有一个好结果,很可能你马上得到EXC_BAD_ACCESS.即使你是幸运的,他们碰巧指向有效的内存,Objective-C运行时会想到它们指向一个有效的Class结构,这是极其不可能的,而这个结果也很可能将是一个EXC_BAD_ACCESS.

  • 不错的答案,但考虑扩展什么是可变参数函数,因为它不是 Objective-C 特定的功能。 (2认同)

KID*_*dAe 3

事实上,"@age"是 aconst char*所以它似乎符合你对什么是 a 的描述exc_bad_access