Middle
È necessario usare un executor asincrono in questo caso?
sobes.tech AI
Risposta dell'AI
Sì, è necessario.
Accedendo a actor dall'esterno del suo contesto isolato (in questo caso dal contesto globale), il compilatore garantisce la sicurezza dei thread, richiedendo che l'accesso avvenga in modo asincrono.
// Protocollo per dimostrazione
protocol DataFetcher {
func fetchData() async -> String
}
actor DataCache {
var cache: [String: String] = [:]
func updateCache(key: String, value: String) {
cache[key] = value // Eseguito all'interno del contesto isolato dell'attore
}
func cachedData(forKey key: String) -> String? {
return cache[key] // Eseguito all'interno del contesto isolato dell'attore
}
nonisolated func clearCacheIsolated() {
// Questa funzione è contrassegnata come non isolata e non ha accesso allo stato dell'attore
// Per accedervi, è richiesta una chiamata asincrona
}
}
class DataLoader {
let cache: DataCache // Riferimento all'attore
init(cache: DataCache) {
self.cache = cache
}
func loadData(key: String) async -> String {
// Accesso asincrono all'attore dall'esterno
if let cached = await cache.cachedData(forKey: key) {
return cached
}
// ... logica di caricamento dati ...
let newData = "Data for \(key)"
// Aggiornamento asincrono dell'attore
await cache.updateCache(key: key, value: newData)
return newData
}
func attemptClearCacheAsync() async {
// Chiamata asincrona al metodo dell'attore dall'esterno
await cache.clearCacheIsolated()
}
func attemptClearCacheDirect() {
// Errore di compilazione:
// Il metodo di istanza 'clearCacheIsolated()' isolato dall'attore non può essere
// chiamato da un contesto non isolato
// cache.clearCacheIsolated()
}
}
In questo esempio:
- I metodi
updateCacheecachedDatavengono eseguiti all'interno del contesto isolato diDataCachee sono accessibili in modo sincrono all'interno dell'attore. - L'accesso a
cache.cachedData(forKey: key)ecache.updateCache(key: key, value: newData)dal metodoloadData(che si trova fuori dal contesto dell'actor) richiede la parola chiaveawait, che indica esecuzione asincrona e utilizzo di un executor asincrono. L'executor dell'actorsi occupa di eseguire queste operazioni in ordine, garantendo accesso esclusivo allo stato dell'actor. - Il metodo
clearCacheIsolatedè contrassegnato comenonisolated, ma anche la sua chiamata asincronaawait cache.clearCacheIsolated()è valida dall'esterno dell'actor, anche se in questo caso non è obbligatoria per garantire la sicurezza dei thread (poiché il metodo non modifica lo stato dell'actor). - La chiamata sincrona diretta
cache.clearCacheIsolated()da un contesto non isolato (come inattemptClearCacheDirect) provoca un errore di compilazione, confermando la necessità di accesso asincrono.
Pertanto, per interagire in modo sicuro con un actor dall'esterno del suo contesto, è necessario utilizzare chiamate asincrone che vengono eseguite con l'aiuto di un executor asincrono gestito dallo stesso actor.