发送邮件到nil? [英] Sending a message to nil?

查看:109
本文介绍了发送邮件到nil?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为一名正在阅读Apple的Objective-C 2.0文档的Java开发人员:我不知道向nil发送消息是什么 - 更不用说它是如何实际有用的。从文档中摘录:


Cocoa
中有几种模式可以利用这个事实。从消息返回到nil

值也可能有效:




  • 如果方法返回一个对象,任何指针类型,大小小于或等于
    的任何整数标量
    sizeof(void *),float,double,a
    long double或long long,然后是
    消息发送到nil返回0。

  • 如果方法返回一个结构,由Mac OS X ABI函数定义
    Call Guide将返回
    寄存器,则发送到nil
    的消息对
    数据结构中的每个字段返回0.0。

  • 如果方法返回除上述值以外的任何值
    键入消息的返回值
    发送到nil未定义。


Java让我的大脑无法解释上面的解释?或者有一些我缺少的东西,会使这清楚如玻璃?



注意:是的,我的确想到了消息/接收器在Objective-C,

解决方案

好吧,我认为这可以用一个非常狡猾的例。假设你有一个Java方法打印出一个ArrayList中的所有元素:

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

现在,如果你调用这样的方法:someObject .foo(NULL);你可能会得到一个NullPointerException当它试图访问列表,在这种情况下在调用list.size();现在,你可能永远不会调用someObject.foo(NULL)与这样的NULL值。然而,你可能已经从一个方法返回NULL,如果它运行一些错误生成ArrayList像someObject.foo(otherObject.getArrayList());



当然,如果你做这样的事情,你也会有问题:

  ArrayList list = NULL; 
list.size();

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

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

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

  [someObject foo:nil]; 



我们有相同的情况,Java将产生一个NullPointerException。nil对象将首先访问[anArray count]但是,而不是抛出一个NullPointerException,Objective-C将简单地返回0根据上面的规则,所以循环不会运行,但是,如果我们设置循环运行设置的次数,我们首先发送一个消息到anArray在[anArray objectAtIndex:i];这也将返回0,但由于objectAtIndex:返回一个指针,指向0的指针是nil / NULL,NSLog将通过循环遍历nil(尽管NSLog是一个函数,而不是一个方法,如果传递一个nil NSString,则打印输出(null) p>

在某些情况下,有一个NullPointerException更好,因为你可以立即告诉程序有问题,但除非你捕获异常,程序会崩溃。 (在C中,试图以这种方式引用NULL会导致程序崩溃。)在Objective-C中,它只是引起可能不正确的运行时行为。但是,如果你有一个方法,如果它返回0 / nil / NULL /一个零结构不打破,那么这将避免你必须检查以确保对象或参数是nil。


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

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

  • 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.

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?

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

解决方案

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());
    }
}

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();

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];

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.

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.

这篇关于发送邮件到nil?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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