“向 nil 发送消息”是什么意思? 意思是,为什么这是一个特殊情况?

发布于 2024-07-26 04:23:04 字数 186 浏览 2 评论 0原文

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

Cocoa中有几种模式 利用这一事实。 这 消息返回值为零 也可能有效:

这是什么意思? 我似乎无法跟上它。

I just started reading the Objective-C tutorials, and there is a section on "sending a message to nil":

There are several patterns in Cocoa
that take advantage of this fact. The
value returned from a message to nil
may also be valid:

What does this mean? I can't seem to follow it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

冷清清 2024-08-02 04:23:04

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 被定义为零,因此运行时将开始从存储在内存中位置零的地址读取信息,这几乎可以保证是访问冲突。

The special treatment of nil means that you can do the following:

SomeClass * someObject;
someObject = nil;
[someObject doSomething];

And you can be assured that nothing will happen.

Now, why is this important?

In Objective-C, sending a message to an object means telling that object to do something, or asking that object for some information. Some examples:

[someObject updateRecords]; // 1
x = [someObject size];      // 2

Line 1 sends someObject a message called updateRecords, and line 2 sends the same object a message called size, which is expected to return a value. These messages boil down to method calls, and the actual code that ends up being run is determined by the Objective-C runtime system, since Objective-C is a dynamically-typed language.

To determine which method to invoke, the runtime system reads information from the address of the object in question (someObject, in the examples above) to work out what class it is an instance of. Using that information, it is able to look up the appropriate method to call, and when all that has been figured out, it executes the code in the method.

If the runtime system did not treat nil as a special case, it would probably crash if you tried to execute the code shown at the top. nil is defined to be zero, so the runtime would start reading information from an address stored at location zero in memory, which is almost gauranteed to be an access violation.

空宴 2024-08-02 04:23:04
  • nil 基本上是一个空指针(即它是存储在指针中的数字零)。
  • 所有传递给 nil 的消息都是合法的(它们不会导致崩溃),但它们不会执行任何操作。
  • 所有返回 nil 的消息都会返回 nil、0、0.0 或 NO,具体取决于返回类型。
  • nil is basically a null pointer (i.e. it is the number zero stored in a pointer).
  • All messages to nil are legal (they won't cause a crash), but they don't do anything.
  • All messages to nil return nil, or 0, or 0.0, or NO, depending on the return type.
无人问我粥可暖 2024-08-02 04:23:04

您可以向 nil 发送任何消息。 什么都没发生。

您在这些文档中到底不明白什么?

You can send any message to nil. Nothing happens.

What exactly is it you don't understand in those docs?

鹤仙姿 2024-08-02 04:23:04

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

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

id thingICareAbout = [obj3 doSomethingElse];

如果您经过几个步骤才能到达 thingICareAbout,则可以节省大量不必要的代码行,而不必在使用前测试 obj1、obj2 等是否为 nil。 如果需要,您可以在最后检查 thingICareAbout 是否为零。 有时,如果您的代码在 nil(或原始值为 0)时仍然可以工作,您甚至不必这样做。

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

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

The great thing about nil messaging compared to other languages like C# is that you can write code that performs multiple method calls without having to test for nil at each step.

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

id thingICareAbout = [obj3 doSomethingElse];

If you go through several steps to get to thingICareAbout, it saves a lot of unnecessary lines of code to not have to test if obj1, obj2 and so on are nil before using them. You can just check if thingICareAbout is nil once at the end if you need to. Sometimes you don't even have to do that, if your code still works when it's nil (or 0 for primitive values).

In C# you would have had to explicitly check if each object is nil, set up exception handling around that block of code, or just hope none of the intermediate objects are ever nil.

One other thing to keep in mind (that I just learned myself!) is that 10.5 changed this behavior-- it used to be that it was only safe for integers and pointers to objects, not structs or floating point values. You might see some additional error checking when you're looking at other code because of this.

我的影子我的梦 2024-08-02 04:23:04

它会做你所期望的事情:什么也不做。

It does what you would expect: nothing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文