Middle
Je potrebné použiť asynchrónneho vykonávateľa v tomto prípade?
sobes.tech AI
Odpoveď od AI
Áno, je to potrebné.
Pri prístupe k actor zvonku z izolovaného kontextu (v tomto prípade z globálneho kontextu) zaručuje prekladač bezpečnosť vlákien, vyžadujúc asynchrónny prístup.
// Demonstratívny protokol
protocol DataFetcher {
func fetchData() async -> String
}
actor DataCache {
var cache: [String: String] = [:]
func updateCache(key: String, value: String) {
cache[key] = value // Beží v izolovanom kontexte aktora
}
func cachedData(forKey key: String) -> String? {
return cache[key] // Beží v izolovanom kontexte aktora
}
nonisolated func clearCacheIsolated() {
// Táto funkcia je označená ako nonisolated a nemá prístup k stavu aktora
// Na prístup je potrebný asynchrónny volanie
}
}
class DataLoader {
let cache: DataCache // Odkaz na aktor
init(cache: DataCache) {
self.cache = cache
}
func loadData(key: String) async -> String {
// Asynchrónny prístup k aktoru
if let cached = await cache.cachedData(forKey: key) {
return cached
}
// ... logika načítania dát ...
let newData = "Data for \(key)"
// Asynchrónne aktualizovanie aktora
await cache.updateCache(key: key, value: newData)
return newData
}
func attemptClearCacheAsync() async {
// Asynchrónne volanie metódy aktora zvonku
await cache.clearCacheIsolated()
}
func attemptClearCacheDirect() {
// Chyba kompilátora:
// Metóda inštancie izolovaná od aktora 'clearCacheIsolated()' nemôže byť
// volaná z ne-izolovaného kontextu
// cache.clearCacheIsolated()
}
}
V tomto príklade:
- Metódy
updateCacheacachedDatasa vykonávajú v izolovanom kontexteDataCachea sú dostupné synchronne vo vnútri aktora. - Volania
cache.cachedData(forKey: key)acache.updateCache(key: key, value: newData)z metódyloadData(ktorá je mimo kontextuactor) vyžadujú kľúčové slovoawait, čo označuje asynchrónne vykonanie a použitie asynchrónneho vykonávateľa. Vykonávateľactorje zodpovedný za vykonanie týchto operácií v poradí, zabezpečujúc exkluzívny prístup k stavuactor. - Metóda
clearCacheIsolatedje označená akononisolated, ale aj na ňu je platné asynchrónne volanieawait cache.clearCacheIsolated()zvonku naactor, hoci to nie je povinné pre zabezpečenie vlákna-bezpečnosti v tomto prípade (pretože táto metóda nemení stavactor). - Priamy synchronný volanie
cache.clearCacheIsolated()z ne-izolovaného kontextu (ako vattemptClearCacheDirect) spôsobí chybu kompilátora, čím potvrdzuje potrebu asynchrónneho prístupu.
Teda, pre bezpečnú interakciu s actor zvonku jeho kontextu je potrebné používať asynchrónne volania, ktoré sa vykonávajú pomocou asynchrónneho vykonávateľa riadeného samotným actor.