Middle
Трябва ли да използвате асинхронен изпълнител в този случай?
sobes.tech AI
Отговор от AI
Да, необходимо е.
Когато достъпвате actor отвън от изолиран контекст (в този случай от глобалния контекст), компилаторът гарантира безопасност на нишките, изисквайки асинхронен достъп.
// Демонстрационен протокол
protocol DataFetcher {
func fetchData() async -> String
}
actor DataCache {
var cache: [String: String] = [:]
func updateCache(key: String, value: String) {
cache[key] = value // Изпълнява се в изолиран контекст на актор
}
func cachedData(forKey key: String) -> String? {
return cache[key] // Изпълнява се в изолиран контекст на актор
}
nonisolated func clearCacheIsolated() {
// Тази функция е маркирана като nonisolated и няма достъп до състоянието на актор
// За достъп е необходим асинхронен повик
}
}
class DataLoader {
let cache: DataCache // Връзка към актор
init(cache: DataCache) {
self.cache = cache
}
func loadData(key: String) async -> String {
// Асинхронен достъп до актор
if let cached = await cache.cachedData(forKey: key) {
return cached
}
// ... логика за зареждане на данни ...
let newData = "Data for \(key)"
// Асинхронно обновяване на актор
await cache.updateCache(key: key, value: newData)
return newData
}
func attemptClearCacheAsync() async {
// Асинхронен повик към метода на актор отвън
await cache.clearCacheIsolated()
}
func attemptClearCacheDirect() {
// Грешка при компилация:
// Методът `clearCacheIsolated()` на актор-изолирана инстанция не може да бъде
// извикан от не-изолирана среда
// cache.clearCacheIsolated()
}
}
В този пример:
- Методите
updateCacheиcachedDataсе изпълняват в изолиран контекст наDataCacheи са достъпни синхронно вътре в актор. - Обажданията към
cache.cachedData(forKey: key)иcache.updateCache(key: key, value: newData)от методаloadData(който е извън контекста наactor) изискват ключовата думаawait, което означава асинхронно изпълнение и използване на асинхронен изпълнител. Изпълнителят наactorотговаря за изпълнението на тези операции в ред, гарантирайки ексклузивен достъп до състоянието наactor. - Методът
clearCacheIsolatedе маркиран катоnonisolated, но дори и към него е валиден асинхронен повикawait cache.clearCacheIsolated()отвън наactor, въпреки че това не е задължително за гарантиране на безопасност на нишките в този случай (тъй като методът не променя състоянието на актор). - Пряк синхронен повик
cache.clearCacheIsolated()от не-изолирана среда (като вattemptClearCacheDirect) води до грешка при компилация, потвърждавайки необходимостта от асинхронен достъп.
Следователно, за безопасно взаимодействие с actor отвън неговия контекст е необходимо да се използват асинхронни повиквания, които се изпълняват с помощта на асинхронен изпълнител, управляван от самия актор.