Освобождение объектов, которые не были созданы - PullRequest
1 голос
/ 16 августа 2011

В большинстве учебных пособий, которые я читал, есть примеры классов с пользовательскими методами init.

Например

@implementation MyPerson

-(id) initWithDefaultName {
self = [super init];
if (self) {
NSString *name = [[NSString alloc] initWithString:@"John Doe"];
}
return self;
}

Теперь я знаю, что должен соединить это с

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

Однако я не понимаю, почему это не произойдет, если я позвоню [MyPerson init], а затем [MyPerson release]

РЕДАКТИРОВАТЬ: Читая комментарии ниже, я понял, что приведенный выше пример кода не совсем правильно. Я понимаю, что мой пользовательский метод initWithName выделяет и инициализирует объект, который не существовал бы, если бы был вызван стандартный метод init. Так что мой метод dealloc содержит код для его освобождения, но он все еще работает, даже если объект name никогда не создавался?

Ответы [ 4 ]

5 голосов
/ 16 августа 2011

Переменные экземпляра имеют значение по умолчанию nil. Отправка сообщения на nil не имеет никакого эффекта.

2 голосов
/ 16 августа 2011

В Java, если вы сделали это:

Foo foo = null;
int bar foo.getBar();

Вы получите исключение нулевого указателя.В Objective-C совершенно нормально отправлять сообщения на nil, это рассматривается как запрет, ничего не делается.

С небольшой оговоркой;методы с возвращаемыми типами, размер которых соответствует принятым ABI соглашениям о возвращении по умолчанию, будут возвращать значение, равное представлению типов данных nil.Так что все это сработает и даст ожидаемые возвращаемые значения:

Foo* foo = nil;
id a = [foo objectValue];    // a will be nil
BOOL b = [foo boolValue];    // b will be NO
int c = [foo intValue];      // c will be 0
float d = [foo floatValue];  // d will be 0.0f

Это может иметь большие преимущества для вашего кода, представьте себе этот пример:

if ([myString length] > 0) {
    // Do stuff here
}

Таким образом, не имеет значения, еслиmyString - пустая строка, или просто nil.Запрашиваемая длина вернет 0 в обоих случаях.Упрощение записи многих операций, поскольку редко приходится учитывать значение nil.

Только для возвращаемых типов, таких как структуры, которые не помещаются в регистр возврата, вы не получите определенное возвращаемое значение:

Foo* foo = nil;
CGRect a = [foo rectValue];  // content of a will be undefined.
1 голос
/ 16 августа 2011

Вы можете отправить что угодно объекту nil, и все будет в порядке.

Вот почему в большинстве учебных пособий для каждого свойства также устанавливается значение nil в их методе viewDidUnload.

1 голос
/ 16 августа 2011

Вы можете безопасно отправить релиз на ноль.Обратите внимание, что вы должны сохранить имя, когда вы назначаете его в своем init, однако.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...