Post on 27-Mar-2020
Experto en Desarrollo de Aplicaciones para Dispositivos Móviles
© 2012-13 Depto. Ciencia de la Computación e IA
Introducción a Xcode y Objective-C
Sesión 3: Objetos y propiedades
Experto en Desarrollo de Aplicaciones para Dispositivos Móviles
Xcode y Objective-C © 2012-13 Depto. Ciencia de la Computación e IA Objetos y propiedades
Puntos a tratar• Definición de una clase• Inicializadores• Gestión de la memoria• Métodos factoría• Patrón singleton• Propiedades• ARC• KVC
2
Experto en Desarrollo de Aplicaciones para Dispositivos Móviles
Xcode y Objective-C © 2012-13 Depto. Ciencia de la Computación e IA Objetos y propiedades
Definición de una clase (.h)
3
@interface UAAsignatura : NSObject { NSString *_nombre; NSString *_descripcion; NSUInteger _horas;} + (CGFloat)creditosParaHoras:(CGFloat)horas;-‐ (CGFloat)creditos;-‐ (CGFloat)tasaConPrecioPorCredito:(CGFloat)precioCredito esBecario:(BOOL)becario; @end
Variables de instancia (protegidas)
Métodos de clase
Métodos de instancia
Nombre de la clase
Hereda de NSObject
Experto en Desarrollo de Aplicaciones para Dispositivos Móviles
Xcode y Objective-C © 2012-13 Depto. Ciencia de la Computación e IA Objetos y propiedades
Implementación de la clase (.m)
4
#import "UAAsignatura.h" const CGFloat UAHorasPorCredito = 10;const CGFloat UADescuentoBecario = 0.5; @implementation UAAsignatura + (CGFloat) creditosParaHoras:(CGFloat)horas { return horas / UAHorasPorCredito;} -‐ (CGFloat)creditos { return [UAAsignatura creditosParaHoras: _horas];} -‐ (CGFloat)tasaConPrecioPorCredito:(CGFloat)precioCredito esBecario:(BOOL)becario { CGFloat precio = [self creditos] * precioCredito; if(becario) { precio = precio * UADescuentoBecario; } return precio;} @end
Experto en Desarrollo de Aplicaciones para Dispositivos Móviles
Xcode y Objective-C © 2012-13 Depto. Ciencia de la Computación e IA Objetos y propiedades
Vista de asistente
5
Experto en Desarrollo de Aplicaciones para Dispositivos Móviles
Xcode y Objective-C © 2012-13 Depto. Ciencia de la Computación e IA Objetos y propiedades
Implementación de inicializadores
6
-‐ (id)initWithNombre:(NSString*)nombre descripcion:(NSString*)descripcion horas:(NSUInteger)horas { self = [super init]; if(self != nil) { _nombre = nombre; _descripcion = descripcion; _horas = horas; } return self;}
Devuelven siempre el tipo id
Inicializa la superclase y asigna el objeto resultante al objeto actual (self)
Si la superclase no ha devuelto un puntero a nulo, inicializa variables de instancia propias
Devuelve el objeto inicializado (self)
Experto en Desarrollo de Aplicaciones para Dispositivos Móviles
Xcode y Objective-C © 2012-13 Depto. Ciencia de la Computación e IA Objetos y propiedades
Inicializador designado• Debe ser invocado por el resto de inicializadores• Suele ser el que lleva un mayor número de parámetros
7
-‐ (id)init;-‐ (id)initWithNombre:(NSString*)nombre;-‐ (id)initWithNombre:(NSString*)nombre descripcion:(NSString*)descripcion horas:(NSUInteger)horas;
-‐ (id)init{ return [self initWithNombre: @"Sin nombre"];} -‐ (id)initWithNombre:(NSString *)nombre{ return [self initWithNombre:nombre descripcion:@"Sin descripcion" horas:-‐1];}
Experto en Desarrollo de Aplicaciones para Dispositivos Móviles
Xcode y Objective-C © 2012-13 Depto. Ciencia de la Computación e IA Objetos y propiedades
Gestión de la memoria
• La gestión se hace contando referencias• Cuando se reserva con alloc el número de referencias es 1• Cuando se copia (copy), el nuevo objeto tiene 1 referencia• Podemos incrementar el número de referencias con retain• Podemos decrementarlo con release• Podemos programar una liberación pendiente con autorelease• Cuando las referencias llegan a 0, se libera la memoria
• Regla de oro• El objeto que retiene (alloc-retain-copy), debe liberar
(release-autorelease)
8
Experto en Desarrollo de Aplicaciones para Dispositivos Móviles
Xcode y Objective-C © 2012-13 Depto. Ciencia de la Computación e IA Objetos y propiedades
Retención y liberación• En el constructor retenemos variables de instancia
• Al liberarse un objeto, se ejecuta su método dealloc• Liberar variables retenidas por el objeto• Llamar a dealloc en la superclase
9
-‐ (id)initWithNombre:(NSString*)nombre descripcion:(NSString*)descripcion horas:(NSUInteger)horas { self = [super init]; if(self != nil) { _nombre = [nombre retain]; _descripcion = [descripcion retain]; _horas = horas; } return self;}
-‐ (void)dealloc { [_nombre release]; [_descripcion release]; [super dealloc];}
Experto en Desarrollo de Aplicaciones para Dispositivos Móviles
Xcode y Objective-C © 2012-13 Depto. Ciencia de la Computación e IA Objetos y propiedades
Gestión en métodos factoría• El propio método debe liberar lo que ha retenido• El objeto debe estar disponible en memoria al menos hasta que lo
recoja quien llamó al método
• Utilizamos autorelease• Guarda la liberación como pendiente en un autorelease pool, que
se llevará a cabo cuando termine la pila de llamadas
10
+ (id)asignaturaWithNombre:(NSString*)nombre descripcion:(NSString*)descripcion horas:(NSUInteger)horas { return [[[UAAsignatura alloc] initWithNombre:nombre descripcion:descripcion horas:horas] autorelease];}
Experto en Desarrollo de Aplicaciones para Dispositivos Móviles
Xcode y Objective-C © 2012-13 Depto. Ciencia de la Computación e IA Objetos y propiedades
Patrón singleton• Podemos utilizar variables de tipo static para implementar el
patrón singleton
• Normalmente crearemos un método de clase con prefijo shared que nos dará acceso a la instacia única
11
+ (UADatosCompartidos) sharedDatosCompartidos { static DatosCompartidos *datos = nil; if(nil == datos) { datos = [[DatosCompartidos alloc] init]; } return datos;}
Una variable local con modificador static sólo se instancia e inicializa la primera vez que el método se ejecuta
Sólo se inicializa a nil la primera vez
Experto en Desarrollo de Aplicaciones para Dispositivos Móviles
Xcode y Objective-C © 2012-13 Depto. Ciencia de la Computación e IA Objetos y propiedades
Propiedades• Las variables de instancia por defecto son protegidas• Podemos incluir modificadores de acceso
@private, @protected, @public• Lo habitual es dejar el valor por defecto y definir getters y setters
• Propiedades• Información a la que se accede mediante getters y setters
12
@property(nonatomic,retain) NSString *nombre;
-‐ (NSString *)nombre;-‐ (void)setNombre: (NSString *)nombre;
Experto en Desarrollo de Aplicaciones para Dispositivos Móviles
Xcode y Objective-C © 2012-13 Depto. Ciencia de la Computación e IA Objetos y propiedades
Definir y sintetizar propiedades• Se definen en la interfaz
• Se sintetizan en la implementación
13
@interface UAAsignatura : NSObject...@property(nonatomic,retain) NSString *nombre;@property(nonatomic,assign) NSUInteger horas; @end
@implementation UAAsignatura @synthesize nombre = _nombre;@synthesize horas = _horas;... @end
Equivale a implementar nombre y setNombre
Crea variable de instancia _nombre de forma automática asociada a la propiedad
Equivale a declarar-‐(NSString*)nombre-‐(void)setNombre: (NSString*)
Los synthesize no son necesarios con Xcode 4.5
Experto en Desarrollo de Aplicaciones para Dispositivos Móviles
Xcode y Objective-C © 2012-13 Depto. Ciencia de la Computación e IA Objetos y propiedades
Acceso a las propiedades• Mediante paso de mensajes a los getters y setters
• Mediante el operador .
• Equivalente a llamar al getter o setter• Se puede utilizar para acceder a cualquier método• No es recomendable abusar de él (sólo usar con propiedades)
14
asignatura.nombre = @"Plataforma iOS";NSLog(@"Nombre: %@", asignatura.nombre);
[asignatura setNombre: @"Plataforma iOS"];NSLog(@"Nombre: %@", [asignatura nombre]);
Experto en Desarrollo de Aplicaciones para Dispositivos Móviles
Xcode y Objective-C © 2012-13 Depto. Ciencia de la Computación e IA Objetos y propiedades
Modificadores de las propiedades• Permiten afinar la forma en la que se definen los getters y
setters• nonatomic
No sincroniza el acceso a la propiedad. Normalmente utilizaremos nonatomic para optimizar.
• readonlySólo genera el getter, para que la propiedad no se pueda
modificar• readwrite
Comportamiento por defecto, genera getter y setter• getter=nombre_getter
Permite especificar el nombre que tendrá el getter• setter=nombre_setter
Permite especificar el nombre que tendrá el setter
15
Experto en Desarrollo de Aplicaciones para Dispositivos Móviles
Xcode y Objective-C © 2012-13 Depto. Ciencia de la Computación e IA Objetos y propiedades
Gestión de la memoria• Utilizamos modificadores para indicar cómo se gestiona la
memoria al asignar valores a las propiedades• assign
Sólo asigna el valor de la propiedad, sin retenerla (retain)• retain
Al asignar un valor libera el anterior (release) y retiene el nuevo (retain)
• copyCrea una copia del objeto al asignar (copy), liberando el valor
anterior. Deberá implementar el protocolo NSCopying
• Si utilizamos retain o copy deberemos liberar las variables en dealloc
16
Experto en Desarrollo de Aplicaciones para Dispositivos Móviles
Xcode y Objective-C © 2012-13 Depto. Ciencia de la Computación e IA Objetos y propiedades
Automatic Reference Counting (ARC)
• Nueva característica de Xcode 4.2• El compilador se encarga de realizar la gestión de la memoria• Debemos seguir una serie de reglas:• Nunca llamar a retain, release o autorelease• No llamar a [super dealloc], el compilador se encarga de ello• No es necesario definir dealloc• No hacer referencias a objetos Objective-C desde estructuras C• No hacer cast entre (id) y (void *)• Los autorelease pools se deben definir mediante la etiqueta:
17
@autoreleasepool { ...}
Experto en Desarrollo de Aplicaciones para Dispositivos Móviles
Xcode y Objective-C © 2012-13 Depto. Ciencia de la Computación e IA Objetos y propiedades
Propiedades con ARC• Ahora hablamos de referencias fuertes y débiles• strong
Referencia fuerte, equivale a retain• weak
Referencia débil. Cuando el objeto es liberado de memoria la referencia se pone a nil automáticamente. Sólo funciona con iOS 5.
• unsafe_unretainedReferencia débil equivalente a assign. Se utiliza para
punteros a objetos. Al ser liberados podríamos tener un error en el acceso.
• assignSe utiliza para tipos de datos básicos.
18
Experto en Desarrollo de Aplicaciones para Dispositivos Móviles
Xcode y Objective-C © 2012-13 Depto. Ciencia de la Computación e IA Objetos y propiedades
Ciclo de retenciones• Debemos seleccionar con cuidado las referencias fuertes y
débiles• Un ciclo de referencias fuertes provoca una fuga de memoria
• Como regla general, las referencias a clases en niveles superiores de la jerarquía deben ser débiles
19
Principal A B
Principal A B
Experto en Desarrollo de Aplicaciones para Dispositivos Móviles
Xcode y Objective-C © 2012-13 Depto. Ciencia de la Computación e IA Objetos y propiedades
Key Value Coding (KVC)• Permite acceder a las propiedades de los objetos como si
fueran entradas de un diccionario
• Permite acceder a las variables aunque sean privadas• Si en un diccionario definimos las claves como cadenas
podemos acceder de la misma forma• Podemos indicar una ruta de propiedades en objetos anidados
20
NSString *nombre = [asignatura valueForKey: @"nombre"];NSNumber *horas = [asignatura valueForKey: @"horas"];
[asignatura setValue:@"Proyecto iOS" forKey:@"nombre"];[asignatura setValue:[NSNumber numberWithInteger:30] forKey:@"horas"];
NSString *nombreCoordinador = [asignatura valueForKeyPath:@"coordinador.nombre"];
Experto en Desarrollo de Aplicaciones para Dispositivos Móviles
Xcode y Objective-C © 2012-13 Depto. Ciencia de la Computación e IA Objetos y propiedades
¿Preguntas...?
21