Вызов метода для неинициализированного объекта (нулевой указатель) - PullRequest
34 голосов
/ 23 апреля 2010
  1. Каково нормальное поведение в 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

Ответы [ 3 ]

61 голосов
/ 23 апреля 2010

Сообщение, отправленное объекту nil, вполне приемлемо в Objective-C, оно рассматривается как неоперативное. Нет способа пометить его как ошибку, потому что это не ошибка, на самом деле это может быть очень полезной функцией языка.

Из документов :

Отправка сообщений на ноль

В Objective-C допустимо отправлять сообщение на ноль - оно просто не имеет никакого эффекта во время выполнения. Есть несколько моделей в какао, которые пользуются этим факт. Значение, возвращаемое из сообщение на ноль также может быть действительным:

  • Если метод возвращает объект, то возвращается сообщение, отправленное на nil 0 (nil), например:

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

    Если aPerson s spouse равно nil, затем mother отправляется на nil и метод возвращает nil.

  • Если метод возвращает любой тип указателя, любой целочисленный скаляр размера меньше чем или равное sizeof(void*), а float, double, long double, или long long, затем сообщение отправлено nil возвращает 0.

  • Если метод возвращает struct, как определено в Mac OS X ABI Руководство по вызову функции должно быть возвращено в регистрируется, затем отправляется сообщение nil возвращает 0.0 для каждого поля в структура данных. Другое struct типы данных не будут заполнены нули.

  • Если метод возвращает что-либо кроме указанного выше значения набирает возвращаемое значение сообщения отправлено на ноль не определено.

13 голосов
/ 01 марта 2012

Из Грег Паркер сайт :

Если работает 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}
6 голосов
/ 23 апреля 2010

Одна вещь, о которой вы должны знать: в Objective-C вы не вызываете метод для объекта, вы отправляете сообщение объектуСреда выполнения найдет метод и вызовет его.

Начиная с первых версий Objective-C, сообщение для nil всегда было безопасным запретом, который возвращает nil.Существует много кода, который зависит от этого поведения.

...