在未初始化的对象上调用方法(空指针)

Flo*_*rin 35 iphone initialization objective-c null-pointer

  1. 如果你在一个对象(指针)上调用一个nil的方法(也许是因为有人忘了初始化它),Objective-C中的正常行为是什么?它不应该产生某种错误(分段错误,空指针异常......)?
  2. 如果这是正常行为,有没有办法改变这种行为(通过配置编译器),以便程序在运行时引发某种错误/异常?

为了使我所说的更清楚,这是一个例子.

有这个课程:

@interface Person : NSObject {

    NSString *name;

}

@property (nonatomic, retain) NSString *name;

- (void)sayHi;

@end
Run Code Online (Sandbox Code Playgroud)

有了这个实现:

@implementation Person

@synthesize name;

- (void)dealloc {
    [name release];
    [super dealloc];
}

- (void)sayHi {
    NSLog(@"Hello");
    NSLog(@"My name is %@.", name);
}

@end
Run Code Online (Sandbox Code Playgroud)

在程序的某个地方,我这样做:

Person *person = nil;
//person = [[Person alloc] init]; // let's say I comment this line
person.name = @"Mike";            // shouldn't I get an error here?
[person sayHi];                   // and here
[person release];                 // and here
Run Code Online (Sandbox Code Playgroud)

Rob*_*ger 63

发送到nil对象的消息在Objective-C中是完全可以接受的,它被视为无操作.没有办法将它标记为错误,因为它不是错误,实际上它可能是该语言的一个非常有用的功能.

来自文档:

发送消息为零

在Objective-C中,将消息发送到nil是有效的 - 它在运行时根本没有效果.Cocoa中有几种模式可以利用这一事实.从消息返回到nil的值也可能是有效的:

  • 如果该方法返回一个对象,则发送一条消息给nilreturns 0(nil),例如:

    Person *motherInLaw = [[aPerson spouse] mother];

    如果aPersonspousenil,随后mother被送到nil并且该方法返回nil.

  • 如果该方法返回任何指针类型,任何大小小于或等于sizeof(void*)a float,a double,a long double或a的整数标量long long,则发送给nil返回的消息0.

  • 如果该方法返回a struct,如Mac OS X ABI函数调用指南所定义的那样在寄存器中返回,那么发送的消息将 nil返回0.0数据结构中的每个字段.其他struct 数据类型不会用零填充.

  • 如果该方法返回除上述值类型之外的任何内容,则发送到nil的消息的返回值是未定义的.

  • 我不知道有任何改变这种行为的方法.它是Objective-C/Cocoa编程的基础部分.你会学会爱它. (3认同)

Hea*_*ers 13

来自Greg Parker网站:

如果运行LLVM Compiler 3.0(Xcode 4.2)或更高版本

Messages to nil with return type | return
Integers up to 64 bits           | 0
Floating-point up to long double | 0.0
Pointers                         | nil
Structs                          | {0}
Any _Complex type                | {0, 0}


NSR*_*der 6

您应该清楚的一点是,在Objective-C中,您不会对象上调用方法,而是对象发送消息.运行时将找到该方法并调用它.

从Objective-C的第一个版本开始,给nil的消息一直是一个安全的无操作,返回nil.有很多代码依赖于这种行为.