Untitled
unknown
swift
3 years ago
3.5 kB
3
Indexable
import UIKit let semaphore = DispatchSemaphore(value: 1) // Класс одиночки определяет статический метод `getInstance`, // который позволяет повторно использовать одно и то же // подключение к APIClient по всей программе. class APIClient { // Конструктор одиночки всегда должен оставаться приватным, // чтобы мы не смогли самостоятельно создавать // экземпляры этого класса через оператор `new`. private init() {} // Поле для хранения объекта-одиночки должно быть объявлено статичным. // Восклицательный знак означает, что мы гарантируем, что поле не будет nil, // даже при учете того, что оно не задано в инициализаторе. private static var shared: APIClient! // Основной статический метод одиночки служит альтернативой // конструктору и является точкой доступа к экземпляру этого // класса. static func getInstance() -> APIClient { if shared == nil { // Заставим остальные потоки дождаться создания объекта semaphore.wait() // На всякий случай ещё раз проверим, не был ли // объект создан другим потоком, пока текущий // ждал освобождения блокировки. if shared == nil { shared = APIClient() } } // Разрешим остальным потокам продолжить выполнение semaphore.signal() return shared } // Предоставляемый функционал func makeRequest() { APIClientLogic.makeRequest() } // Создание еще одного приватного класса обусловлено // стремлением следовать Single Responsibility Principle. // В итоге первый класс отвечает за обеспечение единственного экземпляра, // второй выполняет непосредственную задачу апи клиента. // ВАЖНО: Доступа к APIClientLogic ни у кого нет. Все методы в нем статичны. Никто не сможет создать // экземпляр APIClient, но на всякий случай даже у него мы скрываем инициализатор. private class APIClientLogic { private init() {} static func makeRequest() { /*...*/ } } } // По умолчанию для каждого класса Swift предоставляет возможность использовать метод copy, // создающий новый объект класса. // Переопределим метод, запретив копирование объекта. extension APIClient: NSCopying { func copy(with zone: NSZone? = nil) -> Any { return self } }
Editor is loading...