NSDate init вопрос, связанный с управлением памятью в Objective-C - PullRequest
4 голосов
/ 06 августа 2009

У меня есть NSDate объект, созданный

NSDate *date = [[NSDate alloc] init];

Позже я хочу сбросить дату на "сейчас", поэтому я подумал, что

[date init];

или

date = [date init];

может делать эту работу, но они этого не делают. Вместо

[date release];
date = [[NSDate alloc] init];

работает. Я немного запутался по этому поводу, поскольку в документации для - (id) init написано:

Возвращает объект NSDate, инициализированный для текущей даты и времени.

и поскольку date уже выделен, разве ему просто не нужно сообщение init?

Ответы [ 2 ]

9 голосов
/ 06 августа 2009

Думайте о alloc и init как о логически неразделимых частях конструктора. Вы можете вызывать методы, начинающиеся с «init», только один раз для данного объекта - после того, как объект был инициализирован, и повторная инициализация является ошибкой. Это верно для любого объекта Objective-C, а не только для NSDate. Однако объекты NSDate также неизменны - после создания они не могут измениться.

Причина, по которой последний код работает, заключается в том, что вы создаете новый экземпляр NSDate, что является правильным решением. Вы также можете использовать [NSDate date], чтобы выполнить то же самое. Имейте в виду, что он возвращает объект, которым вы (пока) не владеете, поэтому вам нужно сохранить его, если потребуется, и выпустить его позже.

Помните, что если вы получили объект от кого-то, он уже был инициализирован. (Если нет, то это ошибка программирования в коде, который его предоставил, или это крайне редкое исключение из правила.)

5 голосов
/ 27 января 2010

Если вы хотите получить текущую дату, вы можете просто использовать:

NSDate * now = [NSDate date];

Если вы хотите сохранить его, тогда retain это.

NSDate * now = [[NSDate date] retain];

Вы не можете сбросить NSDate с помощью init, init предназначен только для первоначальной инициализации объекта.

Вы можете просто получить другую дату:

NSDate * now = [[NSDate date] retain];
// use the now object
// need new date
[release now];
now = [[NSDate date] retain];
// once you don't need it release it
[now release];

Сообщение date возвращает autoreleased экземпляр NSDate, следовательно, release или autorelease.

autorelease используется в тех случаях, когда вам не нужно беспокоиться о том, где именно вам нужно освободить объект - он помещается в autorelease pool. Объект в пуле автоматического освобождения освобождается после окончания итерации цикла событий или при вызове команды release в пуле ... (подробнее об документации по управлению памятью в Apple).

Btw. [NSDate date] - это удобный метод, который, вероятно, примерно такой (не гарантируется, что он точно такой же, но функционально похож на):

- (NSDate *)date
{
    return [[[NSDate alloc] init] autorelease];
}
...