在 Objective-C 中向 nil 发送消息 [英] Sending a message to nil in Objective-C

查看:42
本文介绍了在 Objective-C 中向 nil 发送消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为一名正在阅读 Apple 的 Objective-C 2.0 文档的 Java 开发人员:我想知道向 nil 发送消息"是什么意思——更不用说它的实际用途了.从文档中摘录:

As a Java developer who is reading Apple's Objective-C 2.0 documentation: I wonder what "sending a message to nil" means - let alone how it is actually useful. Taking an excerpt from the documentation:

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

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

  • 如果该方法返回一个对象、任何指针类型、任何整数标量大小小于或等于sizeof(void*),一个浮点数,一个双精度数,一个long double 或 long long,然后是发送到 nil 的消息返回 0.
  • 如果该方法返回一个结构体,由 Mac OS X ABI 函数定义呼叫指南返回注册,然后一条消息发送到 nil为每个字段返回 0.0数据结构.其他结构数据类型不会用零填充.
  • 如果该方法返回上述值以外的任何值键入消息的返回值发送到 nil 是未定义的.

Java 是否让我的大脑无法理解上述解释?或者有什么我遗漏的东西可以使它像玻璃一样清晰?

Has Java rendered my brain incapable of grokking the explanation above? Or is there something that I am missing that would make this as clear as glass?

我确实了解了 Objective-C 中的消息/接收器的概念,我只是对恰好是 nil 的接收器感到困惑.

I do get the idea of messages/receivers in Objective-C, I am simply confused about a receiver that happens to be nil.

推荐答案

嗯,我认为可以用一个非常人为的例子来描述.假设您在 Java 中有一个方法可以打印出 ArrayList 中的所有元素:

Well, I think it can be described using a very contrived example. Let's say you have a method in Java which prints out all of the elements in an ArrayList:

void foo(ArrayList list)
{
    for(int i = 0; i < list.size(); ++i){
        System.out.println(list.get(i).toString());
    }
}

现在,如果你像这样调用该方法: someObject.foo(NULL);当它尝试访问列表时,你可能会得到一个 NullPointerException,在这种情况下是在调用 list.size();现在,您可能永远不会像这样使用 NULL 值调用 someObject.foo(NULL) .但是,您可能已经从一个返回 NULL 的方法中获取了 ArrayList,如果它在生成 ArrayList 时遇到一些错误,例如 someObject.foo(otherObject.getArrayList());

Now, if you call that method like so: someObject.foo(NULL); you're going to probably get a NullPointerException when it tries to access list, in this case in the call to list.size(); Now, you'd probably never call someObject.foo(NULL) with the NULL value like that. However, you may have gotten your ArrayList from a method which returns NULL if it runs into some error generating the ArrayList like someObject.foo(otherObject.getArrayList());

当然,如果你这样做,你也会遇到问题:

Of course, you'll also have problems if you do something like this:

ArrayList list = NULL;
list.size();

现在,在 Objective-C 中,我们有等效的方法:

Now, in Objective-C, we have the equivalent method:

- (void)foo:(NSArray*)anArray
{
    int i;
    for(i = 0; i < [anArray count]; ++i){
        NSLog(@"%@", [[anArray objectAtIndex:i] stringValue];
    }
}

现在,如果我们有以下代码:

Now, if we have the following code:

[someObject foo:nil];

我们有同样的情况,Java 会产生 NullPointerException.nil 对象将在 [anArray count] 处首先被访问.然而,Objective-C 不会抛出 NullPointerException,而是根据上述规则简单地返回 0,因此循环不会运行.但是,如果我们将循环设置为运行一定次数,那么我们首先在 [anArray objectAtIndex:i] 处向 anArray 发送消息;这也将返回 0,但由于 objectAtIndex: 返回一个指针,并且指向 0 的指针为 nil/NULL,NSLog 每次通过循环都会传递 nil.(虽然 NSLog 是一个函数而不是一个方法,但如果传递一个 nil NSString,它会打印出(null).

we have the same situation in which Java will produce a NullPointerException. The nil object will be accessed first at [anArray count] However, instead of throwing a NullPointerException, Objective-C will simply return 0 in accordance with the rules above, so the loop will not run. However, if we set the loop to run a set number of times, then we're first sending a message to anArray at [anArray objectAtIndex:i]; This will also return 0, but since objectAtIndex: returns a pointer, and a pointer to 0 is nil/NULL, NSLog will be passed nil each time through the loop. (Although NSLog is a function and not a method, it prints out (null) if passed a nil NSString.

在某些情况下,使用 NullPointerException 会更好,因为您可以立即知道程序有问题,但除非您捕获异常,否则程序将崩溃.(在 C 中,尝试以这种方式取消引用 NULL 会导致程序崩溃.)在 Objective-C 中,它只会导致可能不正确的运行时行为.但是,如果您有一个方法在返回 0/nil/NULL/一个归零的结构时不会中断,那么这将使您不必检查以确保对象或参数为零.

In some cases it's nicer to have a NullPointerException, since you can tell right away that something is wrong with the program, but unless you catch the exception, the program will crash. (In C, trying to dereference NULL in this way causes the program to crash.) In Objective-C, it instead just causes possibly incorrect run-time behavior. However, if you have a method that doesn't break if it returns 0/nil/NULL/a zeroed struct, then this saves you from having to check to make sure the object or parameters are nil.

这篇关于在 Objective-C 中向 nil 发送消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆