ios - llamando a cancelAllOperations desde NSOperations anidadas
Estoy luchando con la siguiente situación, por favor tengan paciencia conmigo ya que he tratado de explicar esto lo más claramente posible:
Tengo una clase CoummintyOperation que es una subclase de GroupOperation. Se llama a CommuityOperation y se agrega a NSOperationQueue. CommunityOperation, a su vez, está llamando a un montón de NSOperations que también son subcasos de GroupOperation y, a su vez, están llamando a NSoperations dentro de ellas. He agregado dependencias para GroupOperationsen la clase CommunityOperation. El problema con el que estoy lidiando es si falla una operación anidada, necesito cancelar TODAS LAS NSOperations en la clase CommunityOperations, pero no tengo acceso a la cola de operación a la que se agregó CommunityOperation para llamar al método cancelAllOperations.
¿Alguien puede ayudarme y explicar cómo puedo llamar a este método, cancelar todas las operaciones en esta clase (y por lo tanto todas las operaciones anidadas) y mostrar un mensaje de error al usuario?
Gracias en advance
Aquí hay un código de muestra para ayudar a explicar mi problema: CommunityOperation se pone en una OperationQueue de otra clase (no incluida)
public class CommunityOperation: GroupOperation {
var updateOperation: UpdateOperation!
var menuOperation: MenuOperation!
var coreDataSaveOperation: CoreDataSaveOperation!
var hasErrors = false
public init() {
super.init(operations: [])
updateOperation = UpdateOperation()
menuOperation = MenuOperation()
coreDataSaveOperation = CoreDataSaveOperation()
coreDataSaveOperation.addDependencies([updateOperation, menuOperation])
self.addOperation(updateOperation)
self.addOperation(menuOperation)
self.addOperation(coreDataSaveOperation)
}
}
Clase MenuOperation, que también tiene Operaciones anidadas:
class UpdateMenuOperation: GroupOperation {
let downloadGroupsOperation: DownloadGroupsOperation
let downloadMembersOperation: DownloadMembersOperation
init() {
downloadGroupsOperation = DownloadGroupsOperation()
downloadMembersOperation = DownloadMembersOperation(])
super.init(operations: [downloadGroupsOperation,
downloadMembersOperation
])
}
}
La clase DownloadGroupOperation es nuevamente una subclase de GroupOperation. Tiene 2 operaciones: la primera para descargar datos y la segunda para analizar los datos:
class DownloadTopGroupsOperation: GroupOperation {
let downloadOperation: DownloadOperation
let importTopGroupsOperation: ImportOperation
init() {
downloadOperation = DownloadOperation()
importOperation = ImportOperation()
importOperation.addDependency(downloadOperation)
importOperation.addCondition(NoCancelledDependencies())
super.init(operations: [downloadOperation, importOperation])
}
}
Y finalmente (vaya) la clase DownloadOperation usa una NSURLSession y el método downloadTaskWithURL, es en el controlador de finalización de este método donde quiero llamar a cancelAllOperations en la operatioQueue principal si se devuelve un error:
class DownloadOperation: GroupOperation {
init() {
super.init(operations: [])
if self.cancelled {
return
}
let task = session.downloadTaskWithURL(url) { [weak self] url, response, error in
self?.downloadFinished(url, response: response as? NSHTTPURLResponse, error: error)
}
}
func downloadFinished(url: NSURL?, response: NSHTTPURLResponse?, error: NSError?) {
if error {
*cancel allOperations on queue*
}
}
}
------------Respuesta------------
Debería funcionar de una manera un poco diferente. Verificaría isCancelled de GroupOperation al final de cada ejecución de NSOperation. Si se canceló la operación, cancele la GroupOperation actual y así sucesivamente. Al final, su CommunityOperation también debería cancelarse.
Aquíes la implementación aproximada de la solución propuesta:
extension GroupOperation {
func addCancellationObservers() {
self.operations.forEach() { init() {
updateOperation = UpdateOperation()
menuOperation = MenuOperation()
coreDataSaveOperation = CoreDataSaveOperation()
coreDataSaveOperation.addDependencies([updateOperation, menuOperation])
// Attach a condition to ensure that all dependencies succeeded
coreDataSaveOperation.addCondition(NoFailedDependenciesCondition())
super.init(operations: [updateOperation, menuOperation, coreDataSaveOperation])
}
.willCancelObservers.append() { [unowned self] operation, errors in
self.cancel() // cancel the group operation. will force it to cancel all child operations
}
}
}
}
Luego llame a addCancellationObservers desde el método init de cada operación de grupo que tenga.
------------Respuesta------------
si está utilizando el código de muestra de Apple (o https://github.com/danthorpe/Operations, que es la evolución de ese proyecto), puede resolver esto agregando una condición a sus operaciones que tienen dependencias.
Aquí está el inicio de su GroupOperation de nivel superior
1008611Para explicar lo que está pasando aquí... NSOperation no tiene el concepto de "fracaso". Las operaciones siempre "terminan", pero si terminaron correctamente o fallaron no afecta el funcionamiento de las dependencias de NSOperation.
En otras palabras, una operación estará lista cuando finalicen todas sus dependencias, independientemente de si esas dependencias se realizaron correctamente. Esto se debe a que el "éxito" y el "fracaso" son algo que la subclase debe definir. Operación (la subclase NSOperation) define el éxito porhaber terminado sin ningún error.
Para solucionar esto, agregue una condición de que ninguna dependencia debe haber fallado. En Operaciones, esta condición se renombró para que quede más clara. Pero el concepto también existe en el código de ejemplo de Apple.
Etiquetas: nsoperation nsoperationqueue swift ios
Artículos relacionados:
ios: recuperación de la matriz bool de NSUserdefaults en Swift
toque de cacao - Haz que la imagen encaje dentro del botón en iOS
- svn - Problema: volver a una revisión modificada y confirmar la revisión principal
- Invocar un comando con evaluación de variables en el script Octopus Deploy Powershell
- twitter bootstrap -, bootstrap_3_layout.html.twig, no funciona con Symfony 3
- c#: está utilizando la descarga a través de http. Actualmente, Unity agrega NSAllowsArbitraryLoads a Info.plist para simplificar la transición
- c# - ¿En qué caso TaskCompletionSource.SetResult() ejecuta la continuación sincrónicamente?
- python - Diagrama gráfico de similitud de palabras proporcionado por Word2Vec
- jquery: ¿es esta la forma de llamar a ajax en php?
- iphone: envíe varias aplicaciones de iOS con la misma base de código
- java: llamada de método de la clase de adaptador a la actividad
- mysql - ¿Pasar una verificación de sesión de juego/cliente de un servidor a otro? (Java)
- Cámara de Android: la vista previa se acerca al grabar video
- html - ¿Puedes asignar una identificación a las pestañas en r shiny flexdashboard?
- javascript - ¿Cómo imprimir $_REQUEST que está disponible dentro de una función AJAX específica?
- ¿Puede Quill limitar el tamaño de la imagen cargada?
- php: muestra el contenido de la página de datos JSON con SSL
Artículos calientes
- medicina china para la bronquitis
- Diferencia entre infección de las vías respiratorias superiores y bronquitis
- ¿Qué causa la epididimitis?
- Criterios diagnósticos de cálculos renales
- ¿Qué medicamento la masturbación causa prostatitis?
- ¿Cuáles son los factores de padecer gota?
- Qué comer durante la convalecencia de una hemorragia cerebral
- que es el alzheimer
- Principales criterios diagnósticos de las bronquiectasias
- ¿Cuáles son las formas de prevenir y tratar la menstruación irregular en las mujeres?
- Síntomas de gota de ternera
- Saco gestacional de 5x4mm cuanto dura el embarazo
- La diferencia entre espinillas y espinillas de ácaros
- Por qué frotar con jengibre puede tratar la caída del cabello
- ¿Cuánto tiempo se puede vivir con insuficiencia hepática?