2010-04-23 78 views
31
  1. 如果您在對象(指針)上調用nil方法(可能是因爲某人忘記初始化它),Objective-C中的正常行爲是什麼?它不應該產生某種錯誤(分段錯誤,空指針異常...)?
  2. 如果這是正常行爲,是否有改變此行爲(通過配置編譯器)的方法,以便程序在運行時引發某種錯誤/異常?

爲了更清楚我在說什麼,下面是一個例子。在未初始化的對象上調用方法(空指針)

有了這個類:

@interface Person : NSObject { 

    NSString *name; 

} 

@property (nonatomic, retain) NSString *name; 

- (void)sayHi; 

@end 

與此實現:

@implementation Person 

@synthesize name; 

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

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

@end 

程序中某個位置我這樣做:

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 

回答

57

發送到nil對象的消息是完全在Objective-C中可以接受,它被視爲無操作。沒有辦法將它標記爲錯誤,因爲它不是錯誤,實際上它可能是該語言的一個非常有用的功能。

docs

發送消息給零

在Objective-C,它是有效的發送 消息爲nil-它只是在運行時沒有效果 。可可中有幾種模式 ,它們充分利用了這個 的事實。從 消息返回到零的值也可以是有效的:

  • 如果該方法返回一個對象,然後消息發送到nil返回 0nil),例如:

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

    如果aPersonspousenil, 然後mother被髮送到nil和 方法返回nil

  • 如果該方法返回任何指針類型,尺寸小於 或等於sizeof(void*)的任何整數標量,一個 float,一個double,一個long double, 或long long,則消息中發送 到nil返回0

  • 如果該方法返回一個struct,如由Mac OS X的ABI 函數調用指南定義爲在 寄存器被返回,則消息中 的數據結構發送至 nil返回0.0每個字段。其他struct 數據類型將不會被充滿 零。

  • 如果該方法返回比上述值以外的任何其他類型的 發送到零的消息 的返回值是未定義的。你應該在明確

+2

而且我不知道有任何的方式來改變這種行爲。這是使用Objective-C/Cocoa進行編程的基本部分。你會學會去愛它。 – 2010-04-23 07:47:38

+0

鏈接到doc中的答案已死(*找不到頁*)。 – Pang 2016-12-07 09:19:04

6

一件事是,在Objective-C,你不通話對象的方法,你將消息發送到的對象。運行時將找到該方法並調用它。

自Objective-C的第一個版本以來,一個消息傳遞給nil一直是一個安全的no-op,返回nil。有很多代碼依賴於這種行爲。

12

Greg Parkersite

如果運行LLVM編譯器3.0(4.2的Xcode)或更高版本

 
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}