En Objective-C, los protocolos y delegados son conceptos fundamentales que permiten la comunicación entre objetos de manera flexible y desacoplada. Este tema es crucial para entender cómo se estructuran muchas aplicaciones iOS y macOS.

¿Qué es un Protocolo?

Un protocolo en Objective-C es similar a una interfaz en otros lenguajes de programación. Define un conjunto de métodos que una clase puede implementar. Los protocolos permiten que las clases se comuniquen entre sí sin necesidad de conocer los detalles internos de las otras clases.

Definición de un Protocolo

Para definir un protocolo, utilizamos la palabra clave @protocol seguida del nombre del protocolo y la lista de métodos que deben implementarse.

@protocol MiProtocolo <NSObject>
- (void)metodoRequerido;
@optional
- (void)metodoOpcional;
@end

En este ejemplo:

  • MiProtocolo es el nombre del protocolo.
  • metodoRequerido es un método que cualquier clase que adopte este protocolo debe implementar.
  • metodoOpcional es un método que las clases pueden implementar si lo desean.

Adopción de un Protocolo

Una clase adopta un protocolo declarando su conformidad con el protocolo en su interfaz.

@interface MiClase : NSObject <MiProtocolo>
@end

Luego, la clase debe implementar los métodos requeridos del protocolo.

@implementation MiClase
- (void)metodoRequerido {
    // Implementación del método requerido
}
@end

¿Qué es un Delegado?

Un delegado es un objeto que actúa en nombre de otro objeto para realizar tareas específicas. En Objective-C, los delegados se utilizan comúnmente para manejar eventos y acciones de manera flexible.

Uso de Delegados

Para utilizar un delegado, primero definimos un protocolo que el delegado debe seguir. Luego, la clase que necesita un delegado declara una propiedad para el delegado y llama a los métodos del protocolo en los momentos apropiados.

@protocol MiDelegado <NSObject>
- (void)tareaCompletada;
@end

@interface MiClaseConDelegado : NSObject
@property (nonatomic, weak) id<MiDelegado> delegado;
- (void)realizarTarea;
@end

@implementation MiClaseConDelegado
- (void)realizarTarea {
    // Realizar alguna tarea
    // ...
    // Notificar al delegado que la tarea se ha completado
    [self.delegado tareaCompletada];
}
@end

Implementación del Delegado

Una clase que actúa como delegado debe adoptar el protocolo y proporcionar implementaciones para los métodos del protocolo.

@interface MiClaseDelegada : NSObject <MiDelegado>
@end

@implementation MiClaseDelegada
- (void)tareaCompletada {
    NSLog(@"La tarea ha sido completada.");
}
@end

Ejemplo Completo

A continuación, se muestra un ejemplo completo que ilustra el uso de protocolos y delegados.

// Definición del protocolo
@protocol ProtocoloDeEjemplo <NSObject>
- (void)procesoFinalizado;
@end

// Clase que utiliza el delegado
@interface ClaseConDelegado : NSObject
@property (nonatomic, weak) id<ProtocoloDeEjemplo> delegado;
- (void)iniciarProceso;
@end

@implementation ClaseConDelegado
- (void)iniciarProceso {
    // Simulación de un proceso
    NSLog(@"Proceso iniciado...");
    // Notificar al delegado que el proceso ha finalizado
    [self.delegado procesoFinalizado];
}
@end

// Clase que actúa como delegado
@interface ClaseDelegada : NSObject <ProtocoloDeEjemplo>
@end

@implementation ClaseDelegada
- (void)procesoFinalizado {
    NSLog(@"El proceso ha finalizado.");
}
@end

// Uso de las clases
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        ClaseConDelegado *objetoConDelegado = [[ClaseConDelegado alloc] init];
        ClaseDelegada *objetoDelegado = [[ClaseDelegada alloc] init];
        
        objetoConDelegado.delegado = objetoDelegado;
        [objetoConDelegado iniciarProceso];
    }
    return 0;
}

Ejercicio Práctico

Ejercicio

  1. Define un protocolo llamado ProtocoloDeNotificacion con un método requerido - (void)notificacionRecibida.
  2. Crea una clase ClaseNotificadora que tenga una propiedad delegada de tipo id<ProtocoloDeNotificacion>.
  3. Implementa un método en ClaseNotificadora que simule el envío de una notificación y llame al método del delegado.
  4. Crea una clase ClaseReceptora que adopte el protocolo ProtocoloDeNotificacion y proporcione una implementación para el método notificacionRecibida.
  5. En el main, crea instancias de ClaseNotificadora y ClaseReceptora, asigna el delegado y prueba la notificación.

Solución

// Definición del protocolo
@protocol ProtocoloDeNotificacion <NSObject>
- (void)notificacionRecibida;
@end

// Clase que envía notificaciones
@interface ClaseNotificadora : NSObject
@property (nonatomic, weak) id<ProtocoloDeNotificacion> delegado;
- (void)enviarNotificacion;
@end

@implementation ClaseNotificadora
- (void)enviarNotificacion {
    NSLog(@"Enviando notificación...");
    [self.delegado notificacionRecibida];
}
@end

// Clase que recibe notificaciones
@interface ClaseReceptora : NSObject <ProtocoloDeNotificacion>
@end

@implementation ClaseReceptora
- (void)notificacionRecibida {
    NSLog(@"Notificación recibida.");
}
@end

// Uso de las clases
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        ClaseNotificadora *notificadora = [[ClaseNotificadora alloc] init];
        ClaseReceptora *receptora = [[ClaseReceptora alloc] init];
        
        notificadora.delegado = receptora;
        [notificadora enviarNotificacion];
    }
    return 0;
}

Conclusión

En esta sección, hemos aprendido sobre los protocolos y delegados en Objective-C, cómo definir y adoptar protocolos, y cómo utilizar delegados para manejar eventos y acciones de manera flexible. Estos conceptos son fundamentales para la programación en Objective-C y son ampliamente utilizados en el desarrollo de aplicaciones iOS y macOS. En el siguiente módulo, exploraremos las categorías y extensiones, que nos permitirán añadir funcionalidades a las clases existentes sin modificar su código fuente original.

© Copyright 2024. Todos los derechos reservados