Comprensión durante la lectura
¿Por qué la comunidad Swift está migrando de RxSwift y Combine?
Combine está recibiendo menos actualizaciones y la comunidad de programación reactiva está perdiendo popularidad.
¿Existe alguna alternativa nativa en Swift 6 para la observación reactiva de valores?
Existe una propuesta en curso SE-475 Transactional Observation of Values que técnicamente permite observar cambios sobre un atributo y procesarlos como si fuera un AsyncSequence:
let names = Observations { person.name }
Task.detached {
for await name in names {
print("Name 1 was updated to: \(name)")
}
}
Task.detached {
for await name in names {
print("Name 2 was updated to: \(name)")
}
}
¿Cómo se implementa el debouncing sin Combine?
$searchQuery
.debounce(for: .milliseconds(500), scheduler: DispatchQueue.main)
.sink(receiveValue: { [weak self] query in
guard !query.isEmpty else {
self?.searchResults = Self.articleTitlesDatabase
return
}
/// A simplified static result and search implementation.
self?.searchResults = Self.articleTitlesDatabase
.filter { $0.lowercased().contains(query.lowercased()) }
})
.store(in: &cancellables)
¿Cómo funciona el reemplazo de un pipeline de debounce usando Task.sleep y cancelación manual?
/// Using manual cancellation management.
func search(_ query: String) {
/// Cancel any previous searches that might be 'sleeping'.
currentSearchTask?.cancel()
currentSearchTask = Task {
do {
/// Debounce for 0.5 seconds to wait for a pause in typing before executing the search.
try await Task.sleep(for: .milliseconds(500))
print("Starting to search!")
guard !query.isEmpty else {
searchResults = Self.articleTitlesDatabase
return
}
/// A simplified static result and search implementation.
searchResults = Self.articleTitlesDatabase
.filter { $0.lowercased().contains(query.lowercased()) }
} catch {
print("Search was cancelled!")
}
}
}
Problema con el NotificationCenter
NotificationCenter.default.publisher(for: .someNotification)
.sink { [weak self] _ in
self?.didReceiveSomeNotification()
}.store(in: &cancellables)
Notifications today rely on an implicit contract that an observer’s code block will run on the same thread as the poster, requiring the client to look up concurrency contracts in documentation, or defensively apply concurrency mechanisms which may or may not lead to issues. Notifications do allow the observer to specify an OperationQueue to execute on, but this concurrency model does not provide compile-time checking and may not be desirable to clients using Swift Concurrency.
Se espera que el observador del NotificationCenter corra en el mismo hilo que emite la notificación.
¿Por qué los closures de sink no ofrecen seguridad en tiempo de compilación con actores?
Combine no está integrado con el sistema de concurrencia de Swift 6, por lo que el compilador no puede verificar si el código dentro de un sink es seguro respecto al aislamiento de actores.
NotificationCenter.default.publisher(for: .someNotification)
.sink { [weak self] _ in
self?.didReceiveSomeNotification()
// ✅ Compila sin errores... pero puede crashear
}.store(in: &cancellables)
// ❌ El compilador advierte que esto es inseguro
NotificationCenter.default.addObserver(...)
El closure de sink es esencialmente una caja negra para el compilador en términos de concurrencia. Swift no sabe en qué hilo se va a ejecutar ese closure, por lo que no puede garantizar que respete el aislamiento del @MainActor.
El riesgo concreto es el siguiente: si una notificación es enviada desde un Task.detached (fuera del hilo principal), el closure de sink se ejecutará en ese mismo hilo, violando el aislamiento del actor y produciendo un crash en tiempo de ejecución, no un error en tiempo de compilación.
Top comments (0)