Estoy en la etapa de diseño de una aplicación que va a utilizar un DESCANSO de servicio web y la suerte de tener un dilema en cuanto a uso asíncrono síncrono vs vs roscado. Aquí está el escenario.

Decir que usted tiene tres opciones para perforar hacia abajo, cada uno con sus propios basados en REST de recursos. Me puede perezosamente cargar cada uno con una solicitud sincrónica, pero que va a bloquear la interfaz de usuario y evitar que el usuario de golpear una vuelta botón de navegación mientras se recuperan los datos. Este caso se aplica en casi cualquier lugar excepto para cuando la aplicación requiere una pantalla de inicio de sesión. Yo no puedo ver ninguna razón para uso sincrónico de las solicitudes HTTP vs asincrónica, debido a que la sola razón. El único momento en que tiene sentido es tener un subproceso de trabajo hacer su solicitud sincrónica, y notificar al hilo principal cuando la solicitud se hace. Esto evitará que el bloque. La pregunta entonces es la marca del banco el código y ver que tiene más sobrecarga, un hilo de solicitud sincrónica o asincrónica solicitud.

El problema con peticiones asíncronas es que usted necesita para configurar una instalación inteligente de la notificación o el delegado del sistema puede tener varias solicitudes para varios recursos sucediendo en un momento dado. El otro problema con ellos es que si tengo una clase, digamos que un singleton que es el manejo de todos mis datos, no se pueden utilizar las peticiones asíncronas en un método getter. Significado de los siguientes no ir:

 - (NSArray *)users {
     if(users == nil)
        users = do_async_request //NO GOOD

     return users;
 }

mientras que la siguiente:

 - (NSArray *)users {
    if(users == nil)
      users == do_sync_request //OK.

    return users;
 }

Usted también podría tener prioridad. A lo que me refiero prioridad es que si se mira de Apple, la aplicación de Correo en el iPhone, te darás cuenta de que la primera chupar toda su POP/IMAP árbol antes de hacer una segunda solicitud para recuperar las 2 primeras líneas (el valor predeterminado) de su mensaje.

Supongo que mi pregunta a los expertos es este. Cuando usted está utilizando asíncronos, síncronos, los hilos, y cuando usted está utilizando ya sea async/sync en un hilo? ¿Qué tipo de delegación sistema de ¿tiene el programa de instalación para saber qué hacer cuando una solicitud asincrónica completa? Estás priorizando su async solicitudes?

Hay una gama de soluciones para este problema muy común. Es muy sencillo hack de algo. El problema es que no quiero hack y yo queremos tener algo que es simple y fácil de mantener.

InformationsquelleAutor Coocoo4Cocoa | 2008-12-16

8 Comentarios

  1. 7

    No creo que hay una respuesta «correcta». Parece que usted entiende los compromisos y usted simplemente necesita para hacer de su diseño alrededor de los.

    Un par de puntos al azar: a veces su aplicación obliga a un enfoque en particular. Por ejemplo, muchos de la conveniencia (es decir, sincrónico) métodos no permitir la autenticación. Para mí eso significaba que mi decisión estaba tomada.

    Para Delicioso terminé no el uso de hilos. He hecho todas mis llamadas de la red asincrónica y he usado el defecto XML parser (que funciona mediante la devolución de llamadas). Ya que todo está controlado por eventos y cada unidad es pequeña, permite que la interfaz de usuario bastante fluido sin tener la complejidad de las operaciones de roscado.

    Yo uso una máquina de estado para averiguar por qué estoy recibiendo una respuesta concreta, y una cola así que sólo tengo que tener una sola operación «en vuelo» en cualquier momento dado. Hay distintos para la mayoría de las solicitudes, de modo que no tienen necesidad de un sistema de prioridad.

    El código de red es el más complejo en mi aplicación y se tomó un largo tiempo de ponerse a trabajar mucho menos robusta!

    • Esteban, creo que un estado de la máquina, así como una cola me ayudaría un montón. Estoy asumiendo que no tienen un ejemplo en cualquier lugar alrededor de?
    • «Estado de la máquina» fue una gran manera de expresar esto… es un par de booleanos y una serie de instrucciones switch. Nada terriblemente inteligente, pero he encontrado dibujo en un trozo de papel de antemano que era útil. La cola es sólo un NSMutableArray.
  2. 8

    Yo no estoy descontando delegado asincrónico llamadas, pero por lo general terminan usando un hilo de la clase de los trabajadores con las solicitudes sincrónicas. Me parece que es más fácil en el largo plazo para tener un lugar bien definido, roscado API, en lugar de llenar su controlador con el código de la gestión del estado, entre los métodos asincrónicos. Usted podría incluso hacer asincrónica en el subproceso de trabajo, aunque por lo general es más fácil usar los métodos sincrónicos, a menos que no admiten una característica que debe utilizar. Por supuesto, todo esto depende de las circunstancias, no puedo pensar en muchas situaciones en las que simplemente el uso de los métodos asincrónicos sería la mejor ruta.

    Considerar definitivamente NSOperationQueue si usted va esta ruta; se simplifica en gran medida la creación de múltiples subprocesos de trabajo, y también es compatible con las prioridades y dependencias entre las operaciones. Ahora hay algunos problemas en 10.5, pero no he oído hablar de cualquier problema en el iPhone.

  3. 1

    Yo personalmente vistazo a lo que se está haciendo, voy a ususally utilizar un asyc solicitud para asegurarse de que la interfaz de usuario no se bloque, sin embargo, PUEDE que durante el transcurso de la solicitud de deshabilitar la interfaz de usuario de mi aplicación.

    Un primer ejemplo de esto está en una de las aplicaciones que he construido con un botón «buscar». Una vez que la búsqueda se activó como una solicitud asincrónica me gustaría desactivar el botón hasta que la respuesta llegó de nuevo, el efectivo limitar la capacidad del usuario para generar una segunda asyc solicitud.

    Hacer esto, al menos puedo evitar la necesidad de priorites, concedido esto sólo funciona si usted puede de una manera fácil de hacer camino, límite de sus usuarios para que una acción a la vez.

  4. 1

    Me gustaría recomendar el asychronous manera, no hay duda. A continuación, cargar la información sólo cuando sea necesario, y el uso de un delegado del sistema para dar esa información al objeto correcto.

    Usted no desea bloquear la interfaz de usuario. Nunca. Y la carga de la información de forma asíncrona permite un mejor control sobre lo que está pasando así que usted puede lanzar un mensaje de error si es necesario.

  5. 1

    Sólo un pensamiento: Si desea utilizar el marco de Pruebas unitarias para el iPhone, usted puede quiere tener sincrónico funcionalidad, ya que podría facilitar la escritura de las pruebas más fácil.

    Sin embargo, algunos de sus APIs no puede trabajar de forma sincronizada, por lo que necesita para convertirlos en la sincronización de tareas. Proporciona el código que realiza la unidad de pruebas se ejecuta en su propio hilo, usted puede escribir un contenedor que va a esperar hasta que el asíncrono tarea ha terminado.

    Para lograr eso, se haría uso de un semáforo: Su función de contenedor se inicia la operación asíncrona y, a continuación, utiliza el semáforo para bloquear propio (es decir, se pone a dormir). La devolución de llamada que indica el final de la async evento libera el semáforo, por lo que el dormir envoltura de hilo puede continuar y volver.

    • HOLA Tomás, estoy corriendo en exactamente este problema en mi unidad de prueba después de la refactorización mi código de sincronización de llamadas a asynch llamadas. Podría usted explicar en más detalle acerca de los semáforos? Si usted tiene un ejemplo, eso sería increíble. Gracias.
    • He aquí un breve ejemplo: NSLock theLock; int estado; – (void) xy:(Miclase)xy terminado:(NSError *)error { estado = -1; [theLock desbloquear]; } – (void) testBasics { Miclase *c = [[Miclase nuevo]]; theLock = [NSLock nuevo]; [theLock lock]; estado = 0; [c doWithDelegate:auto]; [theLock lock]; [theLock desbloquear]; [theLock release]; [c release]; }
  6. 0

    Me gustaría utilizar dispatch_async con sincrónico. De esta manera, usted tiene la ventaja de no delegados/NSNotifications y que no es el bloqueo de

    - (NSArray *)users {
        if(users == nil) {
            users = do_sync_request();
        }
    
        return users;
    }
    
    //now when calling the users method, do this
    
    - (NSArray *)getUsers {
         dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
               NSArray *users = [self users];
               dispatch_sync(dispatch_get_main_queue(), ^{
                     return users;
               }
         }
    }
  7. -1

    ¿Por qué no puede utilizar una solicitud asincrónica así:

    - (NSArray *)users {
         if(users == nil && !didLaunchRequestAlready )
            users = do_async_request //Looks good to me
         return users;
     }

    Asincrónica es absolutamente la única opción – la única pregunta real es si desea comenzar a utilizar hilos separados, o si desea utilizar sólo el asynch llamadas. Empieza por ahí y mirar en el manejo de los hilos si usted realmente necesita.

    • Su instrucción return ejecutaría antes de la solicitud asincrónica se ha terminado, por lo que no obtendrá los resultados, nil.
    • Quizás quieras instalación de un método de delegado/notificación que sería una señal de que la solicitud ha terminado, y rellenar un UITableView o lo que sea.
    • Yo sólo estaba repitiendo el código de la pregunta presentada. En realidad desea regresar a los usuarios ya que más adelante habría sido establecido, y cuando el método asincrónico terminado haría lo @sebnow dijo, señal de que los datos que estaba listo.

Dejar respuesta

Please enter your comment!
Please enter your name here