作为一名正在阅读苹果Objective-C2.0文档的Java开发人员,我想知道"sending a message to nil"是什么意思——更不用说它到底有多有用了.从文件中摘录:

可可有几种模式

  • 如果该方法返回一个对象、任何指针类型、任何整数标量
  • 如果该方法返回Mac OS X ABI函数定义的 struct
  • 如果该方法返回除上述值以外的任何值

Java让我的大脑无法理解上面的解释了吗?还是有什么东西我遗漏了,可以让它像玻璃一样清晰?

在Objective-C中,我确实理解了消息/接收者的概念,我只是对碰巧是nil的接收者感到困惑.

推荐答案

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

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

现在,如果你这样调用这个方法:someObject.foo(空);当它试图访问列表时,您可能会得到一个NullPointerException,在本例中是在对列表的调用中.大小();现在,你可能永远不会叫某个对象.foo(NULL)与空值类似.但是,您可能是从一个方法中获取ArrayList的,如果该方法在生成ArrayList(如someObject)时遇到错误,它将返回NULL.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]处被访问,然而,Objective-C不会抛出NullPointerException,而是根据上述规则简单地返回0,因此循环不会运行.但是,如果我们将循环设置为运行设定的次数,那么我们首先在[anArray objectAtIndex:i]向anArray发送一条消息;这也将返回0,但由于objectAtIndex:返回指针,并且指向0的指针为nil/NULL,因此每次通过循环时,NSLog都将被传递nil.(尽管NSLog是一个函数而不是一个方法,但如果传递了nil NSString,它会输出(null).

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

Objective-c相关问答推荐

iOS8:退出应用程序后不久出现蓝条正在使用您的位置

将类作为参数传递?

如何追踪 SIGABRT 的原因

使用 ARC,什么更好:alloc 或 autorelease 初始化程序?

lldb 无法打印变量值并显示错误:对 'id' 的引用不明确

Objective C const NSString * vs NSString * const

如何删除应用程序指定目录中的所有文件?

使用 Objective-C 查找 IMEI 号码

在 NSString 对象中查找子字符串

iOS6:supportedInterfaceOrientations 不起作用(被调用但界面仍然旋转)

在 Objective C 中使用 extern

以编程方式访问应用标识符前缀

在 32 位和 64 位架构上格式化 NS(U)Integer 时类型转换的替代方法?

Objective-C 中的同步和异步调用与多线程有什么区别?

Objective-c 2.0 中的可选参数?

从带有参数的方法名称创建 Select 器

UICollectionView 断言失败

ARC 下的 NSString 属性应该是强的还是复制的?

如何调整 UITableView 中原型单元格的左边距?

如何判断 WkWebView 是否在 Objective-C 中完成加载?