IOS / Objective-C equivalente de Android AsyncTask

Estoy familiarizado con el uso de AsyncTask en Android: crear una subclase, execute llamada en una instancia de la subclase y onPostExecute se llama en el subproceso UI o subproceso principal. ¿Cuál es el equivalente en iOS?

4 Solutions collect form web for “IOS / Objective-C equivalente de Android AsyncTask”

Respuesta a la pregunta original:

Grand Central Dispatch (GCD) ofrece un mecanismo para realizar tareas en segundo plano, aunque funciona de una manera estructuralmente diferente a AsyncTask. Para realizar algo de forma asíncrona, sólo tiene que crear una cola (como un hilo) y luego pasar un bloque a dispatch_async() que se realizará en segundo plano. Lo encuentro más limpio que AsyncTask, ya que no hay ninguna subclase involucrada; Es más o menos plug-and-play dondequiera que tenga código que desea ejecutar en segundo plano. Un ejemplo:

 dispatch_queue_t queue = dispatch_queue_create("com.yourdomain.yourappname", NULL); dispatch_async(queue, ^{ //code to be executed in the background }); 

Otros Puntos:

1) Devoluciones de llamada

Si desea realizar una tarea en segundo plano y actualizar la interfaz de usuario (o hacer algo en otro hilo) cuando se realiza la tarea de fondo, simplemente puede anidar las llamadas de despacho:

 dispatch_queue_t queue = dispatch_queue_create("com.yourdomain.yourappname", NULL); dispatch_async(queue, ^{ //code to be executed in the background dispatch_async(dispatch_get_main_queue(), ^{ //code to be executed on the main thread when background task is finished }); }); 

2) Colas globales

Al crear una cola, también puede utilizar la función dispatch_get_global_queue() para obtener una cola de despacho global con una determinada prioridad (como DISPATCH_QUEUE_PRIORITY_HIGH ). Estas colas son universalmente accesibles y son útiles cuando se desea asignar varias tareas al mismo hilo / cola. Tenga en cuenta que la memoria es administrada completamente por iOS.

3) Memoria

A veces hay cierta confusión con respecto a la gestión de la memoria y las colas de envío porque tienen sus propias funciones de dispatch_retain / dispatch_release . Sin embargo, tenga la seguridad de que son tratados como objetos Objective-C por ARC, por lo que no necesita preocuparse por llamar a estas funciones. Haciendo referencia a la gran respuesta de rob robinson sobre GCD y ARC, puede ver la documentación que describe la equivalencia de las colas GCD con objetos Objective-C:

 * By default, libSystem objects such as GCD and XPC objects are declared as * Objective-C types when building with an Objective-C compiler. This allows * them to participate in ARC, in RR management by the Blocks runtime and in * leaks checking by the static analyzer, and enables them to be added to Cocoa * collections. * * NOTE: this requires explicit cancellation of dispatch sources and xpc * connections whose handler blocks capture the source/connection object, * resp. ensuring that such captures do not form retain cycles (eg by * declaring the source as __weak). * * To opt-out of this default behavior, add -DOS_OBJECT_USE_OBJC=0 to your * compiler flags. * * This mode requires a platform with the modern Objective-C runtime, the * Objective-C GC compiler option to be disabled, and at least a Mac OS X 10.8 * or iOS 6.0 deployment target. 

4) Múltiples Tareas / Bloques

Voy a añadir que GCD tiene una interfaz de agrupación compatible con la sincronización de múltiples bloques asíncronos si una tarea no puede continuar hasta múltiples actividades asincrónicas han completado. Jörn Eyrich y ɲeuroburɳ proporcionan una generosa explicación de este tema aquí . Si usted necesita esta funcionalidad, recomiendo encarecidamente tomar unos minutos para leer las dos respuestas de cerca y entender las diferencias entre ellos.

La documentación tiene una gran cantidad de información sobre el tema si usted está tan inclinado.

No hay clases para eso en iOS pero puedes simularlo usando colas. Puedes llamar:

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //Your code to execute in background... }); 

Para las tareas asíncronas y dentro de su código asíncito llame a la siguiente cola para hacer algo en la vista …:

 dispatch_async(dispatch_get_main_queue(), ^{ //Your code to execute on UIthread (main thread) }); 

A continuación, utilizando estas dos colas, puede crear una clase asyncTask, añada esta clase a su proyecto para implementarlas:


 // // AsyncTask.h // // Created by Mansour Boutarbouch Mhaimeur on 25/10/13. // #import <Foundation/Foundation.h> @interface AsyncTask : NSObject - (void) executeParameters: (NSArray *) params; - (void) preExecute; - (NSInteger) doInBackground: (NSArray *) parameters; - (void) postExecute: (NSInteger) result; @end 

 // // AsyncTask.m // // Created by Mansour Boutarbouch Mhaimeur on 25/10/13. // #import "AsyncTask.h" @implementation AsyncTask - (void) executeParameters: (NSArray *) params{ [self preExecute]; __block NSInteger result; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ result = [self doInBackground:params]; dispatch_async(dispatch_get_main_queue(), ^{ [self postExecute:result]; }); }); } - (void) preExecute{ //Method to override //Run on main thread (UIThread) } - (NSInteger) doInBackground: (NSArray *) parameters{ //Method to override //Run on async thread (Background) return 0; } - (void) postExecute: (NSInteger) result{ //Method to override //Run on main thread (UIThread) } @end 

Este es un ejemplo que estoy usando en un proyecto:


 #import "AsyncTask.h" #import "Chat.h" @interface SendChatTask : AsyncTask{ NSArray * chatsNotSent; } @end 

 #import "SendChatTask.h" @implementation SendChatTask - (void) preExecute{ //Method to override } - (NSInteger) doInBackground: (NSArray *) parameters{ //Method to override NSString *sendChatsURL = [NSString stringWithFormat:@"%@%@%@",HOST, NAMESPACE,URL_SEND_CHAT]; chatsNotSent = [parameters objectAtIndex:0]; NSString *response; NSMutableDictionary *params = [[NSMutableDictionary alloc] init]; //... NSError *error; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:[ChatJSONParser wrapChatArray: chatsNotSent] options:0 error:&error]; NSString *JSONString = [[NSString alloc] initWithBytes:[jsonData bytes] length:[jsonData length] encoding:NSUTF8StringEncoding]; [params setObject:JSONString forKey:@"chats"]; response = [HTTPClient executePOST:sendChatsURL parameters:params]; if([respuesta isEqualToString:@"true"]){ return 1; }else{ return -1; } } - (void) postExecute: (NSInteger) result{ //Method to override if (result == 1) { for (Chat *chat in chatsNotSent) { chat.state = STATE_NOT_SENT; [chat save]; AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; [appDelegate refreshChat]; } } else { } } @end 

Y la siguiente llamada:

 [[[SendChatTask alloc] init] executeParameters:[NSArray arrayWithObjects: chatsNotSent, nil]]; 

Puede agregar un método de actualización publishProgress() y respectivo … No lo uso por el momento porque llamo a mi tarea asíncrona en servicios de fondo.

Espero que sea útil.

Si su orientación iOS Versión anterior (que iOS 4 para Grand Central Dispatch) podría utilizar los métodos NSObject executeSelector

  • Ejecutar en el hilo de fondo performSelectorInBackground: withObject:

  • Y ejecutar en MainThread performSelectorOnMainThread: withObject: waitUntilDone:

Esto es un ejemplo:

 [self performSelectorInBackground:@selector(executeInBackground) withObject:nil]; -(void) executeInBackground { NSLog(@"executeInBackground"); [self performSelectorOnMainThread:@selector(executeOnMainThread) withObject:nil waitUntilDone:NO]; } -(void) executeOnMainThread { NSLog(@"executeOnMainThread"); } 

Swift 3

En Android cuando quería ejecutar una tarea en un subproceso de fondo y luego actualizar la interfaz de usuario al finalizar, utilicé AsyncTask ( ejemplo ). Ahora, cuando estoy haciendo versiones de iOS de mis aplicaciones, uso Grand Central Dispatch (GCD) para hacer lo mismo. Así es como se hace con Swift:

 DispatchQueue.global(qos: .background).async { // code to be run on a background task DispatchQueue.main.async { // code to be run on the main thread after the background task is finished } } 

Notas

  • Grand Central Dispatch Tutorial para Swift
  • ¿Cómo puedo obtener un objeto File de PhoneGap camera.getPicture?
  • Trabajadores web en navegadores móviles
  • IOS / Android: diseño de aplicaciones, todo-nativo o PhoneGap?
  • Desarrollo de iOS y Android en Windows
  • Symfony2 - Cómo comprobar si estamos siendo llamados desde un dispositivo móvil
  • Vídeo como imagen de fondo ionic app
  • SVN Repositorio para el código común -phonegap
  • Añadir HTML / JS / CSS GUI a la aplicación OpenGL (Android e iOS)
  • Android contrapartida de la advertencia de memoria iOS
  • ¿Cómo puedo mostrar pdf en html (respuesta / solución de navegación cruzada)
  • WebApp usando webRTC para videochat multiplataforma en iOS Browser y Android Chrome
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.