2015-06-22 2 views
0

Попытка получить класс Singleton в Swift. Я не получаю никаких ошибок, но его просто не работает должным образом.Swift Singleton не работает

Вот код:

// The Singleton class: 
class DataWarehouse { 
    class var sharedData:DataWarehouse { 
     struct Static { 
      static var onceToken : dispatch_once_t = 0 
      static var instance : DataWarehouse? = nil 
     } 
     dispatch_once(&Static.onceToken) { 
      Static.instance = DataWarehouse() 
     } 
     return Static.instance! 
    } 

    // Here's a variable that I want to pass around to other classes: 
    var x = 10 

} 

Далее я создал два класса, которые могут получить доступ к значению x и использовать его, изменить его значение, и т.д.:

class ClassA { 

    var theData = DataWarehouse() 

    func changeX() { 
     // First, log out the current value of X: 
     println("ClassA ==> x is currently: \(theData.x)") 

     // Next, change it: 
     theData.x = -50 
     println("ClassA ==> x was just set to: \(theData.x)") 
    } 

} 

Вот второй класс - его в основном так же, как ClassA:

class ClassB { 

    var theData = DataWarehouse() 

    func changeX() { 
     // First, log out the current value of X: 
     println("ClassB ==> x is currently: \(theData.x)") 

     // Next, change it: 
     theData.x = -88 
     println("ClassB ==> x was just set to: \(theData.x)") 
    } 

} 

Наконец, в main.swift Я положил все это вместе:

let objectA = ClassA() 
objectA.changeX() 

let objectB = ClassB() 
objectB.changeX() 

Выход я получаю:

ClassA ==> x is currently: 10 
ClassA ==> just set x to: -50 
ClassB ==> x is currently: 10 
ClassB ==> just set x to: -88 

Таким образом, значение x на самом деле не обновляется, его всегда 10.

Что утра Я делаю неправильно?

ответ

3

Если вы используете этот метод одиночных игр, для фактического доступа к singleton вам нужно использовать DataWarehouse.sharedData, а не DataWarehouse(), когда вы «создаете» объект datawarehouse в других классах.

В настоящий момент вы фактически не получаете доступ к sharedInstance.

Если вы используете Swift 1.2 и хотите, вы можете использовать некоторые более чистый текст с константами класса (ленивым инициализирован):

class Singleton { 

    static let sharedInstance = Singleton() 

    init() { 
     println("Hello"); 
    } 

} 
+0

У меня нет ничего под названием 'DataWarehouse.sharedInstance'. Думаю, вы имели в виду' DataWarehouse.sharedData'? В любом случае, я попробовал вашу более короткую версию (я действительно использую Swift 1.2) - она ​​работает. И это довольно интересно. Я так привык называть конструктор с '()', но здесь мы получаем доступ к свойству класса ('sharedInstance') - и ** it ** делает экземпляр. Kinda loopy :-) Но я получаю его, его статическое распределение, и он работает - очень круто. Благодаря! – sirab333

+0

Woops typo (я вообще называю это sharedInstance) Я поправлю свой ответ! –

+0

правильный ответ, но вы также должны сделать метод init() закрытым (по умолчанию он является общедоступным) –

0

Как описано выше, но делают INIT частные, так что экземпляры вынуждены использовать sharedInstance

class Singleton { 
    static let sharedInstance = Singleton() 
    private init() { 
     // Only methods within the class can access here 
    } 
} 

Тогда

let single = Singleton() // Is not allowed by the compiler 

Вы должны использовать

let single = Singleton.sharedInstance