каков первый шаг в (NSTimer выпускают и делают недействительным)?

Ошибка в компиляторе / IDE

У меня недавно была эта проблема, и оказалось , это была ошибка в Visual Studio Express 2013 . Мне пришлось удалить исходный файл из проекта и повторно добавить его, чтобы устранить ошибку.

Попытки попробовать, если вы считаете, что это может быть ошибка в компиляторе / IDE:

  • Очистить проект (некоторые IDE имеют возможность сделать это, вы также можете сделать это вручную, удалив объектные файлы)
  • Попробуйте начать новый проект, скопировав весь исходный код из исходного.

5
задан KlimczakM 9 September 2015 в 11:34
поделиться

4 ответа

Эти два метода делают разные вещи. Если у вас есть таймер (вы его сохранили, назначили или скопировали), вам следует его освободить. Если вы запланировали его в цикле выполнения, вы должны сделать его недействительным, чтобы цикл выполнения освободил его. Если вы сделали и то, и другое, то вы должны разблокировать и аннулировать таймер (однако обычно достаточно иметь цикл выполнения, владеющий таймером).

8
ответ дан 18 December 2019 в 06:36
поделиться

Всегда, выпуск - это последнее, что вы делаете.Когда вы что-то выпускаете, нет гарантии, что разыменовать объект безопасно, а это значит, что отправлять ему ЛЮБОЕ сообщение больше не безопасно.

1
ответ дан 18 December 2019 в 06:36
поделиться

[сброс таймера] необходимо вызывать только в том случае, если вы «владеете» таймером. Из документации Apple:

Поскольку цикл выполнения поддерживает таймер, с точки зрения управления памятью обычно нет необходимости сохранять ссылку на таймер после того, как вы его запланировали. Поскольку таймер передается в качестве аргумента, когда вы указываете его метод в качестве селектора, вы можете аннулировать повторяющийся таймер, когда это необходимо в этом методе. Однако во многих ситуациях вам также может понадобиться возможность аннулировать таймер - возможно, даже до его запуска. В этом случае вам нужно сохранить ссылку на таймер, чтобы вы могли отправить ему сообщение о недействительности, когда это необходимо. Если вы создаете незапланированный таймер (см. «Незапланированные таймеры» ), тогда вы должны поддерживать надежную ссылку на таймер (в среде с подсчетом ссылок вы сохраняете его), чтобы он не освобождался перед его использованием.

Что это значит?

Если вы alloc и init таймер, вы также должны освободить его, например:

NSTimer * timer = [[NSTimer alloc] initWith...];

NSRunLoop * runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer:timer forMode:NSDefaultRunLoopMode];
[timer release];

...
...

[timer invalidate];
timer = nil;

После того, как таймер был добавлен в цикл выполнения, нет причин для сохранения ссылки на него больше нет, так как он принадлежит циклам выполнения. В этом случае, как показано, вы должны освободить таймер, как только добавите его в цикл выполнения, а затем просто аннулировать , когда закончите. Последняя строка (установка таймера на nil ) предназначена для безопасности. Вызов invalidate приведет к освобождению таймера (циклом выполнения), поэтому сохранять ссылку, указывающую на него, небезопасно. Установка локальной ссылки на nil сохраняет кошерность.

Если, однако, вы создаете таймер, используя один из удобных методов, например:

NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval ...];

Вам не нужно звоните [сброс таймера] вообще! Удобный метод добавляет таймер в цикл выполнения, который затем владеет им, поэтому вам не нужно выполнять какое-либо управление памятью для возвращенного объекта таймера. Вы бы просто аннулировали таймер, когда больше не хотите его использовать:

[timer invalidate];
timer = nil;

Или, если таймер не был настроен на повторение, вы бы вообще ничего не делали, так как он будет выпущен после его первое обращение.

NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval ...];

Вам не вообще нужно вызывать [сброс таймера] ! Удобный метод добавляет таймер в цикл выполнения, который затем владеет им, поэтому вам не нужно выполнять какое-либо управление памятью для возвращенного объекта таймера. Вы бы просто аннулировали таймер, когда больше не хотите его использовать:

[timer invalidate];
timer = nil;

Или, если таймер не был настроен на повторение, вы бы вообще ничего не делали, так как он будет выпущен после его первое обращение.

NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval ...];

Вам не вообще нужно вызывать [сброс таймера] ! Удобный метод добавляет таймер в цикл выполнения, который затем владеет им, поэтому вам не нужно выполнять какое-либо управление памятью для возвращенного объекта таймера. Вы просто аннулируете таймер, когда больше не хотите его использовать:

[timer invalidate];
timer = nil;

Или, если таймер не был настроен на повторение, вы бы вообще ничего не делали, так как он будет выпущен после его первое обращение.

15
ответ дан 18 December 2019 в 06:36
поделиться

Это правильный способ освободить таймер, который все еще может быть запущенным (и вы хотите остановиться).

0
ответ дан 18 December 2019 в 06:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: