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

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

问题描述

作为一名Java开发人员,正在阅读Apple的Objective-C 2.0文档:我想知道"将消息发送到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:

可可中有几种模式 利用这一事实.这 从消息返回到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:

  • 如果该方法返回一个对象,任何指针类型,任何整数标量 大小小于或等于 sizeof(void *),一个浮点数,一个双精度数,一个 长双倍,或长长,然后一个 发送到nil的消息返回0.
  • 如果该方法返回Mac OS X ABI函数定义的结构 通话指南将被退回 注册,然后将一条消息发送到nil 为该字段中的每个字段返回0.0 数据结构.其他结构数据 类型不会用零填充.
  • 如果该方法返回上述值以外的任何值 输入消息的返回值 发送到nil是不确定的.
  • If the method returns an object, any pointer type, any integer scalar of size less than or equal to sizeof(void*), a float, a double, a long double, or a long long, then a message sent to nil returns 0.
  • If the method returns a struct, as defined by the Mac OS X ABI Function Call Guide to be returned in registers, then a message sent to nil returns 0.0 for every field in the data structure. Other struct data types will not be filled with zeros.
  • If the method returns anything other than the aforementioned value types the return value of a message sent to nil is undefined.

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的情况相同.将首先在[anArray count]处访问nil对象.但是,按照上面的规则,Objective-C不会返回NullPointerException,而是直接返回0,因此不会运行该循环.但是,如果我们将循环设置为运行一定次数,那么我们首先要通过[anArray objectAtIndex:i]向anArray发送一条消息;这也将返回0,但是由于objectAtIndex:返回一个指针,并且指向0的指针为nil/NULL,因此每次通过循环时,NSLog都会被传递为nil. (尽管NSLog是一个函数而不是一个方法,但是如果传递了nil NSString,它将输出(空).

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/归零结构时不会中断,那么就不必检查对象或参数是否为nil.

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天全站免登陆