質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
スレッドセーフ

マルチスレッド環境において、複数のスレッド上で常に正常に実行する事が可能なコードを、スレッドセーフなコードと呼びます。

マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

2760閲覧

Swift コレクションのスレッドセーフな利用方法を教えてください

thirdesr34

総合スコア36

スレッドセーフ

マルチスレッド環境において、複数のスレッド上で常に正常に実行する事が可能なコードを、スレッドセーフなコードと呼びます。

マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2021/05/07 01:03

前提・実現したいこと

シングルトンパターンのオブジェクトをマルチスレッドで利用したく、下記のコードを作成したところ、コレクションへの代入(updateValue)でEXC_BAD_ACCESSのエラーが発生します。
コレクション型をスレッドセーフで利用する方法を教えてください。

Swift

1import Foundation 2public class SingletonTest:NSObject { 3 4 static let shared = SingletonTest() 5 6 override init() { 7 super.init() 8 } 9 10 private var testDictionary:[Int:URL] = [:] 11 12 func testTask (url:URL, key:Int) { 13 testDictionary.updateValue(url, forKey:key) 14 print("Stored Value:(testDictionary[key])") 15 } 16} 17 18func testTask() { 19 let testObject = SingletonTest.shared 20 for keyIndex in 0..<5 { 21 DispatchQueue.global(qos: .utility).asyncAfter(deadline: .now()) { 22 testObject.testTask(url: URL(fileURLWithPath: "http://example.com/(keyIndex)/"), key: keyIndex) 23 } 24 } 25} 26

補足情報(FW/ツールのバージョンなど)

Swift 5
Xcode 12.5

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

thirdesr34

2021/05/07 07:48

ありがとうございました。今回はコンカレントキューを利用することにしました。
guest

回答1

0

自己解決

コンカレントキューを利用することでスレッドセーフにできました。

Swift

1import Foundation 2public class SingletonTest:NSObject { 3 4 static let shared = SingletonTest() 5 private let concurrentQueue = DispatchQueue(label: "concurrentQueue", attributes: .concurrent) 6 7 override init() { 8 super.init() 9 } 10 11 private var testDictionary:[Int:URL] = [:] 12 13 func testTask (url:URL, key:Int) { 14 self.concurrentQueue.async(flags: .barrier) { 15 self.testDictionary.updateValue(url, forKey:key) 16 } 17 self.concurrentQueue.sync { 18 let value:String = testDictionary[key]?.absoluteString ?? "" 19 print("Stored Value:(value)") 20 } 21 } 22} 23 24func testTask() { 25 let testObject = SingletonTest.shared 26 for keyIndex in 0..<5 { 27 DispatchQueue.global(qos: .utility).asyncAfter(deadline: .now()) { 28 testObject.testTask(url: URL(fileURLWithPath: "http://example.com/(keyIndex)/"), key: keyIndex) 29 } 30 } 31}

投稿2021/05/07 07:48

thirdesr34

総合スコア36

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問