Objective c 什么是;向nil发送消息;我的意思是,为什么这是一个特例?

Objective c 什么是;向nil发送消息;我的意思是,为什么这是一个特例?,objective-c,null,Objective C,Null,我刚开始阅读Objective-C教程,其中有一节是关于“向nil发送消息”的: 可可有几种模式 他们利用了这个事实。这个 从消息返回的值为零 也可以是有效的: 这是什么意思?我好像听不懂。你可以给nil发任何信息。什么也没发生 在这些文档中,您到底不了解什么?它做了您所期望的事情:什么都没有。对nil的特殊处理意味着您可以执行以下操作: SomeClass * someObject; someObject = nil; [someObject doSomething]; 你可以放心,什么也不

我刚开始阅读Objective-C教程,其中有一节是关于“向
nil
发送消息”的:

可可有几种模式 他们利用了这个事实。这个 从消息返回的值为零 也可以是有效的:


这是什么意思?我好像听不懂。

你可以给nil发任何信息。什么也没发生


在这些文档中,您到底不了解什么?

它做了您所期望的事情:什么都没有。

nil
的特殊处理意味着您可以执行以下操作:

SomeClass * someObject;
someObject = nil;
[someObject doSomething];
你可以放心,什么也不会发生

现在,为什么这很重要

在Objective-C中,向对象发送消息意味着告诉该对象做某事,或者向该对象询问一些信息。一些例子:

[someObject updateRecords]; // 1
x = [someObject size];      // 2
第1行发送
someObject
一条名为
updateRecords
的消息,第2行向同一对象发送一条名为
size
的消息,该消息预计将返回一个值。这些消息归结为方法调用,最终运行的实际代码由Objective-C运行时系统确定,因为Objective-C是一种动态类型的语言

为了确定调用哪个方法,运行时系统从相关对象的地址读取信息(
someObject
,在上面的示例中),以确定它是哪个类的实例。使用这些信息,它能够查找要调用的适当方法,当所有这些都被解决后,它将执行该方法中的代码


如果运行时系统没有将
nil
视为特例,那么如果您试图执行顶部显示的代码,它可能会崩溃
nil
被定义为零,因此运行时将开始从存储在内存中零位置的地址读取信息,这几乎是一种访问冲突。

与C#等其他语言相比,nil消息传递的优点在于,您可以编写执行多个方法调用的代码,而无需在每个步骤测试nil

id obj1 = [SomeClass object];
id obj2 = [obj1 doSomething];
id obj3 = [obj2 anotherMethod];

id thingICareAbout = [obj3 doSomethingElse];
如果您通过几个步骤来获得
ThingIcareAAbout
,就可以节省大量不必要的代码行,而不必在使用它们之前测试obj1、obj2等是否为零。如果需要,您只需在末尾检查一下
ThingIcareAuto
是否为零。有时,如果代码为nil(或原语值为0)时仍能工作,甚至不必这样做

在C#中,您必须显式地检查每个对象是否为nil,围绕该代码块设置异常处理,或者只希望中间对象中没有一个是nil

要记住的另一件事(我自己刚学会!)是10.5改变了这种行为——过去它只对整数和指向对象的指针安全,而不是结构或浮点值。因此,在查看其他代码时,您可能会看到一些额外的错误检查。

  • nil基本上是一个空指针(即,它是指针中存储的数字零)
  • 所有发送给nil的消息都是合法的(它们不会导致崩溃),但它们不会做任何事情
  • 所有发送到nil的消息都返回nil、0、0.0或NO,具体取决于返回类型

什么是零?是否将值null设置为对象的方法?还是将值null发送到消息?什么消息?“nil”是空对象。如果您熟悉Java,“向nil发送消息”相当于Java中的“在null上调用方法”,只是在Java中,您会得到一个NullPointerException,而在Objective-C中,什么都不会发生。因此,您可以安全地执行类似“[nil doThis:withThis]”这样的操作,程序就不会崩溃(该方法只会返回nil)。Nil等于0,它不是一个对象。这就是为什么可以对返回整数值的方法执行相同的操作。有一个特殊的NSNull对象可以在collections类中使用,但它不等于nil。@Marc:所有对象的计算结果都等于某个整数。您可以向nil发送消息(对于Objective-C中的每个对象都是真的,而对于非对象则不是真的),因此至少在概念上,nil可以有意义地称为对象。但它是一个特殊的值。“nil”通常指nil实例,“nil”通常指nil类。我认为在GNU运行时,它们实际上是显式强制转换(id)0和(Class)0,但我目前只能访问NS运行时。10.5之前的运行时将nil和nil定义为0,但10.5将它们定义为u_DARWIN_NULL。第3点取决于运行时。在旧的运行时,文档中说如果不能返回消息的返回值,如果返回的是浮点、双倍或大于自然字大小的变量,那么熟悉java、C++或C++等流行语言的人就不会期望这会什么都不做。他们预计会出现异常或崩溃。那么为什么在中,他们说“向解除分配的内存发送消息会导致崩溃”?如果释放对象但仍保留指向旧内存位置的指针,则可能会向解除分配的内存(也称为僵尸)发送消息。例如:
[someobjectrelease];[someObject someMethod]。这与
someObject=nil非常不同;[someObject someMethod]即使将someObject设置为nil可能会在GC环境中释放它,但将其设置为nil也会阻止您向释放的内存发送消息。