|
1 | 1 | # 属性\(Attributes\) |
2 | 2 |
|
3 | | -最終更新日: 2024/6/10 |
| 3 | +最終更新日: 2025/2/22 |
4 | 4 | 原文: https://docs.swift.org/swift-book/ReferenceManual/Attributes.html |
5 | 5 |
|
6 | 6 | 宣言と型に情報を追加する。 |
@@ -93,7 +93,60 @@ _version number_ は、ピリオド\(`.`\)で区切られた 1〜3 個の正の |
93 | 93 |
|
94 | 94 | _version number_ は、ピリオド\(`.`\)で区切られた 1〜3 個の正の整数で構成されます。 |
95 | 95 |
|
96 | | -* `message` 引数は、deprecated または obsoleted された宣言に使用した際に、コンパイラが表示する警告またはエラーのテキストメッセージを提供します。形式は次のとおりです: |
| 96 | +* `noasync` 引数は、宣言されたシンボルが非同期コンテキストで直接使用できないことを示します |
| 97 | + |
| 98 | +Swift の並行処理では、潜在的な中断ポイント後に異なるスレッドで再開される可能性があるため、スレッドローカルストレージ、ロック、ミューテックス、セマフォなどを中断ポイントをまたいで使用すると、誤った結果につながる可能性があります。 |
| 99 | + |
| 100 | +この問題を回避するには、シンボルの宣言に `@available(*, noasync)` 属性を追加します: |
| 101 | + |
| 102 | +```swift |
| 103 | +extension pthread_mutex_t { |
| 104 | + @available(*, noasync) |
| 105 | + mutating func lock() { |
| 106 | + pthread_mutex_lock(&self) |
| 107 | + } |
| 108 | + |
| 109 | + @available(*, noasync) |
| 110 | + mutating func unlock() { |
| 111 | + pthread_mutex_unlock(&self) |
| 112 | + } |
| 113 | +} |
| 114 | +``` |
| 115 | + |
| 116 | +この属性は、誰かが非同期コンテキストでそのシンボルを使用しようとした場合にコンパイルエラーを発生させます。また、`message` 引数を使用してシンボルに関する追加情報も提供できます。 |
| 117 | + |
| 118 | +```swift |
| 119 | +@available(*, noasync, message: "Migrate locks to Swift concurrency.") |
| 120 | +mutating func lock() { |
| 121 | + pthread_mutex_lock(&self) |
| 122 | +} |
| 123 | +``` |
| 124 | + |
| 125 | +潜在的に安全でないシンボルを安全に使用できると保証できるのであれば、同期関数でラップし、その関数を非同期コンテキストから呼び出せます。 |
| 126 | + |
| 127 | +```swift |
| 128 | +// noasync 宣言を持つメソッドの同期ラッパを提供する |
| 129 | +extension pthread_mutex_t { |
| 130 | + mutating func withLock(_ operation: () -> ()) { |
| 131 | + self.lock() |
| 132 | + operation() |
| 133 | + self.unlock() |
| 134 | + } |
| 135 | +} |
| 136 | + |
| 137 | +func downloadAndStore(key: Int, |
| 138 | + dataStore: MyKeyedStorage, |
| 139 | + dataLock: inout pthread_mutex_t) async { |
| 140 | + // 非同期コンテキストでラッパを安全に呼び出す |
| 141 | + dataLock.withLock { |
| 142 | + dataStore[key] = downloadContent() |
| 143 | + } |
| 144 | +} |
| 145 | +``` |
| 146 | + |
| 147 | +`noasync` 引数はほとんどの宣言で使用できますが、デイニシャライザの宣言では使用できません。Swift は同期・非同期の両方のコンテキストからクラスのデイニシャライザを呼び出せる必要があります。 |
| 148 | + |
| 149 | +* `message` 引数は、`deprecated` や `obsoleted`、`noasync` が付与された宣言に使用した際に、コンパイラが表示する警告またはエラーのテキストメッセージを提供します。形式は次のとおりです: |
97 | 150 |
|
98 | 151 | ```swift |
99 | 152 | message: <#message#> |
|
0 commit comments