У меня есть одноэлементный класс в моем приложении, который создается при запуске приложения и всегда используется. Теперь я собираюсь ввести NSTimer, который периодически вызывает один из методов singleton, поэтому я понимаю, что таймер сохранит сильную ссылку на мой одноэлементный класс (поскольку одноэлементный класс является целью). Это верно? Что еще более важно, это сильный цикл сохранения проблемы для одного класса, который должен жить в течение всего времени приложения? Если да, то почему?Является ли сильный цикл сохранения релевантным соображением для одного класса, который должен существовать для жизни приложения?
ответ
Я считаю, что это проблема. Одиночный класс уже сложно реорганизовать и повторно использовать. Добавление цикла сохранения в один приведет к тому, что класс, который намного сложнее изменить или повторно использовать в будущем. Когда вы обнаружите, что вам нужен этот класс (или, по крайней мере, набор обязанностей, на который этот таймер является частью), чтобы не быть синглом, вам также нужно запомнить или идентифицировать эту утечку памяти и исправить ее как часть вашего рефактора. Будущее, вероятно, будет печальным.
Вместо этого вы можете написать класс, который следует за хорошими шаблонами (для управления памятью и т. Д.) Независимо от того, доступен ли он как одноэлементный или нет. В вашем случае это может означать сохранение слабой ссылки на таймер («Note in particular that run loops maintain strong references to their timers, so you don’t have to maintain your own strong reference to a timer after you have added it to a run loop.») и аннулирование этого таймера, если этот объект освобожден.
Вы спрашиваете:
У меня есть одноэлементный класс в моем приложении, которое создается при запуске приложения и всегда в использовании. Теперь я собираюсь ввести
NSTimer
, который периодически вызывает один из методов singleton, поэтому я понимаю, что таймер сохранит сильную ссылку на мой одноэлементный класс (поскольку одноэлементный класс является целью). Это верно?
Да, NSTimer
будет поддерживать сильную ссылку на этот экземпляр класса singleton. Эта сильная ссылка сохраняется до тех пор, пока вы не станете таймером (или в случае не повторяющегося таймера, пока не загорится таймер).
Что еще более важно, это сильный цикл сохранения проблемы для одноэлементного класса, который должен жить в течение всего времени приложения? Если да, то почему?
Тот факт, что запланированный экземпляр NSTimer
поддерживает сильную ссылку на цель его обработчика, само по себе не является проблемой. Вы просто должны знать об этом факте и управлять своей памятью соответствующим образом. Все это означает, что если вы закончили с каким-либо объектом, который является объектом NSTimer
, вы несете ответственность за ручное вызов invalidate
этого таймера.
Единственный момент, когда эта сильная ссылка на обработчик таймера становится проблематичной, - это когда вы имеете дело с каким-либо объектом, который имеет более временный характер (например, контроллер вида, который позже может быть отклонен). Слишком часто люди думают: «О, я просто invalidate
, что NSTimer
в методе dealloc
», но это не работает. Метод Objective-C dealloc
(а также метод Swift deinit
) не вызывается до тех пор, пока не будет более сильных ссылок, поэтому вы не можете попытаться устранить сильную ссылку этого таймера в dealloc
, потому что dealloc
не может быть вызван до тех пор, пока таймер недействителен. Вместо этого, если вы закончили с целью NSTimer
, вы должны вручную указать таймер (например, в случае примера контроллера просмотра люди часто делают это в viewDidDisappear
).
В вашем случае тот факт, что у вас есть запланированный повторяющийся таймер, вызывающий метод singleton, не является проблемой. Просто имейте в виду, что этот одноэлементный объект (который, скорее всего, никогда не выпадет из области видимости), не может быть освобожден до тех пор, пока запланированный NSTimer
все еще активен. Вам нужно будет invalidate
NSTimer
, чтобы устранить сильную ссылку на эту цель.
Два дополнительных наблюдений:
Вы описали это
NSTimer
поведение в качестве сильного опорного цикла (цикл удержания). Технически это не сильный ссылочный цикл, а скорее факт, что графикNSTimer
сохраняется в цикле выполнения, на котором он запланирован, а затем таймер сохраняет цель, на которую запланирован ее обработчик.Это несколько академическое различие (потому что оно проявляет себя подобно сильному эталонному циклу), но это стоит отметить.
Вы также должны знать, что вместо использования
NSTimer
вы также можете использовать таймер источника отправки GCD. Таким образом, создать свойство таймера в классе:@property (nonatomic, strong) dispatch_source_t timer;
А затем создать экземпляр и запустить таймер:
typeof(self) __weak weakSelf = self; self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue()); dispatch_source_set_timer(self.timer, DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC, 0); dispatch_source_set_event_handler(self.timer, ^{ [weakSelf handleTimer]; }); dispatch_resume(self.timer);
Эта модель, в отличие от
NSTimer
подхода, не сохраняет цель таймера (или , в этом случае объект, по которому мы ссылаемся черезself
) из-за использования шаблонаweakSelf
в блоке (который разрешает любой сильный опорный цикл). Таким образом, мы в конечном итоге в таймере, который безопасно выпущен, когда объект, который содержит это освобождаться, без сильного опорного цикла.
Сохранять цикл не может быть проблематичным в это время, как вы используете одноплодной, который не нуждается в открепление, но что, если в будущем кто-то еще refactors одноэлементных в обычный класс?
Другое соображение состоит в том, что NSTimer
не очень энергоэффективны, и Apple warmly recommends переключается на GCD
источники для выполнения задач, связанных с таймером. Возможно, вы даже сможете сломать цикл сохранения через ссылки weak
с этим подходом.
- 1. Целевой цикл жизни и цикл сохранения объекта
- 2. Является ли время процессора релевантным для Hyperthreading?
- 3. Является ли «объединение потоков» релевантным для Go?
- 4. Является ли межпроцессное общение релевантным для iPhone или iPad?
- 5. Является ли функциональное программирование релевантным для веб-разработки?
- 6. Является ли изучение JFrame релевантным для разработки Android-игр
- 7. Является ли порядок тегов релевантным для действительного XML?
- 8. Сильный ссылочный цикл в UITableView
- 9. POJO генерируется из генерирующего jsonschema2pojo класса, который не должен существовать
- 10. Должен ли существовать метод responsesToSelector?
- 11. Использование класса приложения Android для сохранения данных
- 12. Является ли ViewState релевантным в ASP.NET MVC?
- 13. Что является местом для жизни
- 14. Не удается найти элемент, который должен существовать?
- 15. Сильный пароль для KeyStore
- 16. Будет ли цикл сохранения?
- 17. Какой образ жизни использовать для консольного приложения?
- 18. Является ли режим параллелизма релевантным, если мы используем PerCall instancing?
- 19. Создает ли [self new] в блоке сильный ссылочный цикл?
- 20. Должен ли я быть захвачен как сильный в обработчике UIAlertAction?
- 21. Может ли цикл существовать в std :: forward_list?
- 22. Должен ли я использовать объекты DataMapper только для целей сохранения?
- 23. Должен ли я писать итераторы для класса, который является только оболочкой вектора?
- 24. Confused на закрытии сильный справочный цикл?
- 25. Должна ли служба просто существовать для кеширования?
- 26. jbossHome 'null' должен существовать
- 27. Является ли yuidoc @namespace релевантным с Ember-CLI?
- 28. Должен ли файл opencv2/text.hpp существовать?
- 29. .net цикл жизни страницы
- 30. Какова продолжительность жизни статической переменной класса библиотеки для Android?
Тот факт, что вы имеете дело с синглом, должен быть неактуальным. Используйте надлежащее управление памятью независимо от того, что. – rmaddy
Где, по вашему мнению, есть цикл удержания? Имеет ли синглтон ссылку на таймер? –
Если ваш синглтон создает повторяющийся таймер, который вызывает метод вашего синглтона, а singleton поддерживает сильную ссылку на таймер, то да, у вас есть цикл сохранения. Тем не менее, это действительно только академическая проблема, так как ваш синглтон сохраняется для жизни вашего приложения. Сохранять циклы являются плохими, если они заставляют объекты сохраняться в памяти после того, как все другие ссылки на них будут выпущены. –