[解決済み] Swiftでdispatch_onceのシングルトンモデルを使う
質問
Swiftで使用するための適切なシングルトン・モデルを考え出そうとしています。これまでのところ、私は非スレッドセーフモデルを次のように動作させることができました。
class var sharedInstance: TPScopeManager {
get {
struct Static {
static var instance: TPScopeManager? = nil
}
if !Static.instance {
Static.instance = TPScopeManager()
}
return Static.instance!
}
}
シングルトンインスタンスをStatic構造体でラップすることで、複雑なネーミングスキームなしでシングルトンインスタンスと衝突しない単一のインスタンスが可能になり、物事をかなりプライベートなものにすることができるはずです。しかし、明らかに、このモデルはスレッドセーフではない。そこで、私は
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
を正しく定義してください。
どのように解決するのですか?
tl;dr: この機能を使用するには クラス定数 Swift 1.2 以降を使用していて ネストされた構造体 を使用すると、以前のバージョンをサポートする必要があります。
Swift の経験から、遅延初期化とスレッドセーフをサポートする Singleton パターンを実装するための 3 つのアプローチがあります。
クラス定数
class Singleton {
static let sharedInstance = Singleton()
}
Swift はクラスの定数 (および変数) を遅延して初期化するので、このアプローチは遅延初期化をサポートします。
let
. これは現在
公式に推奨されている方法
のインスタンスを作成することができます。
クラス定数は Swift 1.2 で導入されました。以前のバージョンの Swift をサポートする必要がある場合は、以下のネストされた構造体のアプローチか、グローバル定数を使用してください。
ネストした構造体
class Singleton {
class var sharedInstance: Singleton {
struct Static {
static let instance: Singleton = Singleton()
}
return Static.instance
}
}
ここでは、ネストされた構造体の静的定数をクラス定数として使用しています。これは Swift 1.1 以前の静的クラス定数の欠落に対する回避策であり、関数内の静的定数や変数の欠落に対する回避策としてもまだ機能します。
ディスパッチ・オンセ
従来のObjective-CのアプローチをSwiftに移植したものです。ネストされた構造体のアプローチに勝る利点はないと確信していますが、構文の違いが興味深いので、とりあえずここに載せておきます。
class Singleton {
class var sharedInstance: Singleton {
struct Static {
static var onceToken: dispatch_once_t = 0
static var instance: Singleton? = nil
}
dispatch_once(&Static.onceToken) {
Static.instance = Singleton()
}
return Static.instance!
}
}
こちらをご覧ください ギットハブ プロジェクトでユニットテストを行っています。
関連
-
[解決済み] メインスレッドチェッカー バックグラウンドスレッドで呼び出された UI API: -[UIApplication applicationState].
-
フォールスルーの使用方法概要
-
[解決済み] Swiftのコンストラクタ
-
[解決済み] 静的クラスとシングルトンパターンの違い?
-
[解決済み] Pythonでシングルトンを作成する
-
[解決済み] Swiftで#pragmaマーク?
-
[解決済み] Objective-CでGCDのdispatch_onceを使用してシングルトンを作成する
-
[解決済み】C++ シングルトンデザインパターン
-
[解決済み】プログラムによってナビゲーションのタイトルを変更する
-
[解決済み】Swiftのenumのカウントを取得する方法は?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] これを解決するにはどうしたらいいのでしょうか。UILabel.textは、メインスレッドからのみ使用する必要があります。
-
[解決済み] Swift 3、Swift 4、それ以降で dispatch_sync, dispatch_async, dispatch_after などはどうすればいいですか?
-
[解決済み] Swiftのコンストラクタ
-
[解決済み] swiftの"? "の意味は何ですか?[重複している]。
-
[解決済み] Swift: print() vs println() vs NSLog()
-
[解決済み】Swiftでオブジェクトが与えられた型かどうかを確認する
-
[解決済み】Swift - StringをDoubleに変換する方法
-
[解決済み】SwiftでFloatをIntに変換する。
-
[解決済み】swift言語におけるstructureとclassの比較
-
[解決済み] 非同期ネットワークリクエストのswift forループの実行が終了するまで待つ