2017-04-13 6 views
5

私はとてもとしてシングルトンクラスを持っている:Swift Class Singletonインスタンスのスレッドを安全にする方法はありますか?

class Database { 
    static let instance:Database = Database() 
    private var db: Connection? 

    private init(){ 
     do { 
     db = try Connection("\(path)/SalesPresenterDatabase.sqlite3") 
     }catch{print(error)} 
    } 
} 

は今、私はクラス内の関数を実行するためにDatabase.instance.xxxxxxを使用して、このクラスにアクセスします。しかし、別のスレッドからインスタンスにアクセスすると、別のインスタンスを作成しようとするような奇妙な結果がスローされます。私は同じスレッドでインスタンスを参照する必要がありますか?

は奇妙な結果がデータベースを示し明確にするために、I /一度にDBにアクセスしようとしているため、2つのインスタンスのOエラー

更新
データベース・コードの詳細は、この質問を参照してください。Using transactions to insert is throwing errors Sqlite.swift

+6

スウィフトシングルトンの作成はスレッドセーフです。これは、シングルトンインスタンスで呼び出す関数が魔法のようにスレッドセーフであることを意味するものではありません。関数をスレッドセーフにする必要がある場合は、セマフォ、シリアルディスパッチキュー、または操作キューのようなものを使用する必要があります。 – Paulw11

+0

'しかし、別のスレッドからインスタンスにアクセスすると、別のインスタンスを作成しようとしたような奇妙な結果になります。あなたの 'Database'クラスの現在の定義を考えると、**インスタンスを2つ作成することはできません。しかし、おそらくあなたが表示していないそのクラスにもっとコードがあります。 BTW:クラスの最後の改良:サブクラス化を防ぐためには、それを 'final'として宣言する必要があります。 –

+0

クラス内の追加コードは** addRow **機能を示します。この関数は、alamofire補完ブロックで呼び出され、データを挿入できない場所でエラーをスローします。興味深いことに、私は私のDatabase.instanceへのすべての呼び出しを削除する場合。シングルトンとコードの問題のビットを最初に実行させる、それは正常に動作します... –

答えて

5
class var shareInstance: ClassName { 

    get { 
     struct Static { 
      static var instance: ClassName? = nil 
      static var token: dispatch_once_t = 0 
     } 
     dispatch_once(&Static.token, { 
      Static.instance = ClassName() 
     }) 
     return Static.instance! 
    } 
} 

利用:聞かせてオブジェクト:クラス名= ClassName.shareInstance

スウィフト3.0

class ClassName { 
    static let sharedInstance: ClassName = { ClassName()}() 
} 

使用:スウィフト3.0のclassname = ClassName.shareInstance

+0

私はswift3を使用しているので、dispatch_once_tオプションは私には利用できません.... –

1

デフォルト()初期化子を使用してから他の人を防ぐために、民間のinitを追加:オブジェクトはしましょう。

class ClassName { 
    static let sharedInstance = ClassName() 
    private init() {} //This prevents others from using the default '()' initializer for this class. 
} 
関連する問題