Шаблон проектирования Одиночка (Singleton) в Objective-C (с ARC)
В прошлом году я выучил насколько важными могут быть синглтоны в песочнице IOS. Чаще всего такие объекты могут без проблем создаваться и использоваться в глобальной области видимости (во всяком случае, большую часть времени). И после того как я понял, что для работы с моделями данных я могу использовать именно синглтоны, я решил изучить как Apple применяет низкоуровневые блоки кода для создания единственного экземпляра класса.
Синглтоны
Если вы создавали iPhone или iPad приложения, которые делают какие-нибудь вызовы к RESTful API, то вы уже определенно видели синглтоны, так как они довольно легко создаются (а также ими часто злоупотребляют) - для тех из вас, у кого нет опыта, простой пример:
Проблемы реализации синглтона
Но существует несколько проблем с такой реализацией, о которых вы должны знать.
Во-первых, этот метод создания класса НЕ потоково-безопасен, поэтому если несколько потоков попытаются получить доступ к этому объекту в одно и тоже время, то вы создадите условия для ситуации гонки.
Несмотря на то, что Apple показал этот пример в старой документации (iOS 4.0+), сегодня вы не должны использовать его.
Если вы захотите использовать синглтоны, используйте dispatch_once()
dispatch_once()
решает эту проблему, потому что:
- он гарантирует, что блок будет вызван только однажды на протяжении жизни этого приложения;
- он потоково-безопасен, и
- благодаря низкоуровневой параллельности, он быстрее, чем другие методы типа @synchronous()
Потокобезопасная реализация синглтона
“При одновременном вызове из нескольких потоков, эта функция синхронно ждет до тех пор, пока блок выполнится”
Вот шаблон для создания синглтонов получше:
|
|
Это наиболее безопасный (и наиболее эффективный) путь к созданию единственного экземпляра класса. Не существует возможного способа создания 2 экземпляров и данный пример на 100% потокобезопасен.