2012-09-13 22 views
6

Estoy tratando de seguir ejemplos de otros, así como de Apple. Estoy perdido.Escribiendo mi propio método de bloqueo

Tengo una clase singleton que utilizo para manejar mi inicio de sesión de usuario (desafía un servidor web, etc.).

Quiero crear un bloque al que pueda llamar, paso el nombre de usuario/contraseña. El bloque realizará las llamadas al servicio web y luego regresará si fue exitoso o no.

Esto es lo que he arreglo para conseguir trabajo hasta el momento:

Mi clase Singleton se ve así:

.h

typedef void (^AMLoginBlock)(NSString *userName, NSString *password); 

@interface AuthManager : NSObject 
+ (id)sharedManager; 

+ (bool)loginUserWithBlock:(AMLoginBlock)block; 

@end 

.m

@implementation AuthManager 

+ (id)sharedManager 
{ 
    static dispatch_once_t pred = 0; 
    __strong static id _sharedObject = nil; 
    dispatch_once(&pred, ^{ 
     _sharedObject = [[self alloc] init]; // or some other init method 
    }); 
    return _sharedObject; 
} 

+ (bool)loginUserWithBlock:(AMLoginBlock)block { 
    NSLog(@"im printing from AM"); 
    return true; 
} 

@end 

I a continuación, llamar al método de esta manera:

bool rtn = [AuthManager loginUserWithBlock:^(NSString *userName, NSString *password) { 
     NSLog(@"im here in the block LVC."); 
    }]; 

Mi pregunta es tres partes:

  1. ¿Cómo escribo un controlador de finalización para el bloque similar a UIView animation... bloque.

  2. ¿Es una buena idea realizar estas llamadas al servicio web desde una implementación basada en bloques?

  3. ¿Debo declarar el método de bloques de este modo:

    - (bool)loginUserWithBlock:(AMLoginBlock)block;

en lugar de utilizar +(bool)loginUser.. ya que está en una clase singleton. No estoy seguro si esto causará que se creen varias instancias del singleton.

Mi objetivo es poder llamar a este bloque como usted llama al [UIView animation..]. Por lo que simplemente puede hacer:

[AuthManager loginUserWithUsername:foo 
          password:bar1 
         completion:^(BOOL finished) { 
          if (finished) 
           //push new view controller. 
          else 
           //spit out error 
        }]; 

Respuesta

6

Finalización Handler

Usted tendrá que copiar el bloque de terminación a una Ivar clase:

@property (nonatomic, copy) void (^completionHandler)(bool *); 

Debido a que está guardando el bloque, es necesario tener un método no de clase toma el bloque (ver a continuación para saber cómo hacerlo sin violar su singleton). Un ejemplo de su método podría ser:

- (void)loginUserWithUsername:(NSString *)username 
        password:(NSString *)password 
        completion:(void(^)(bool *finished))completionBlock 
{ 
    // Copy the blocks to use later 
    self.completionHandler = completionBlock; 

    // Run code 
    [self doOtherThings]; 
} 

Luego, cuando su código de inicio de sesión ha terminado su trabajo, puede llamar al bloquear - aquí me pase auto.error, un bool al bloque:

- (void)finishThingsUp 
{ 
    // We are done with all that hard work. Lets call the block! 
    self.completionHandler(self.error); 

    // Clean up the blocks 
    self.completionHandler = nil; 
} 

buena idea

Bueno, esto es una cuestión filosófica, pero voy a decir esto: Bloques en Objective-C le permiten escribir código que realiza una sola tarea e integrarlo fácilmente en muchos programas. Si opta por no utilizar un controlador de finalización en su código de inicio de sesión que se necesita el código de inicio de sesión para:

  • Requerir que las clases de usarlo implementar un protocolo (como en un LoginDelegate)
  • uso algún otro sistema de informar su código como clave Valor observar o Notificaciones
  • código difícil que trabajar sólo con un tipo de llamada clase

Cualquiera de los métodos anteriores están muy bien, me siento una llamada sistema basado en bloque es el más sencillo y más flexible. Le permite usar su clase sin preocuparse por la infraestructura adicional (configuración de notificaciones, conformidad con protocolos, etc.) al tiempo que le permite reutilizarla en otras clases o programas.

singelton

Métodos que comiencen con un + en Objective-C son métodos de clase. No puede usar métodos de clase para manipular iVars, ya que ¿quién sería el propietario de esos datos?

Lo que puedes hacer es tener un método de clase que siempre devuelve la misma instancia de esa clase, lo que te permite tener un objeto que puede poseer datos, pero evita tener más de uno.

This excellent Stack Overflow answer has sample code.

¡Buena suerte!

Cuestiones relacionadas