Я намагаюся розробити відповідну однотонну модель для використання в Swift. Поки що мені вдалося отримати безпечну модель без потоку, яка працює як:
class var sharedInstance: TPScopeManager {
get {
struct Static {
static var instance: TPScopeManager? = nil
}
if !Static.instance {
Static.instance = TPScopeManager()
}
return Static.instance!
}
}
Обгортання одиночного екземпляра в статичну структуру повинно дозволяти одному екземпляру, який не стикається з одиночними екземплярами без складних схем іменування, і він повинен робити речі досить приватними. Очевидно, що ця модель не є безпечною для потоків. Тому я спробував додати dispatch_once
до всього:
class var sharedInstance: TPScopeManager {
get {
struct Static {
static var instance: TPScopeManager? = nil
static var token: dispatch_once_t = 0
}
dispatch_once(Static.token) { Static.instance = TPScopeManager() }
return Static.instance!
}
}
Але я отримую помилку компілятора в dispatch_once
рядку:
Неможливо перетворити тип виразу 'Void' у тип '()'
Я спробував кілька різних варіантів синтаксису, але всі вони, мабуть, мають однакові результати:
dispatch_once(Static.token, { Static.instance = TPScopeManager() })
Яке правильне використання dispatch_once
Swift? Спочатку я вважав, що проблема пов'язана з блоком через ()
повідомлення про помилку, але чим більше я на це дивлюся, тим більше я думаю, що це може бути питання dispatch_once_t
правильного визначення.
@lazy
повинна бути безпечною для потоків.
Static.instance = TPScopeManager()
примушує тип екземпляра. Якщо ви використовуєте щось на зразок Static.instance = self()
необхідного ініціалізатора, буде створено відповідний клас типу. Незважаючи на це, і це важливо зазначити, лише один раз для всіх випадків в ієрархії! Перший тип для ініціалізації - це набір типів для всіх екземплярів. Я не думаю, що цілі-c поводилися так само.