iOS para desarrolladores .NET: Clases en Objetive-C parte 1

jueves, 22 de enero de 2015


En el anterior artículo empezó esta serie sobre iOS para desarrolladores .NET, donde veíamos una introducción a la historia y las herramientas o lenguaje que vamos a utilizar en la serie.

En esta primera parte sobre clases vamos ver como se definen las clases Objetive-C en comparación a C# y las propiedades dentro de la misma.

En la serie voy a ir comparando Objetive-C y C# pero muchas de las comparaciones se podrán aplicar también a Java porque se parece bastante a C#.

Orientación a Objetos

Al igual que C#, Objetive-C es un lenguaje orientado a objetos, ya que es una adaptación del lenguaje C gracias a Cocoa, donde vamos a tener unos tipos primitivos como números, boleanos propios del lenguaje C y objetos como string, arrays, diccionarios, que aporta el framework Foundation de Cocoa, estos últimos tendrán el prefijo NS y las que nosotros nos creemos, deberián tener por convención un prefijo de 3 letras en mayúscula.

Ficheros de clase

C#

En C# tenemos un fichero con extensión .cs por clase y podemos tener una clase o varias dentro del fichero.

Objetive-C

En Objetive-C una clase se divide en dos ficheros, uno con extensión .h que es la cabecera y otro .m que es la implementación, se puede añadir más de una cabedera en el .h y mas de una implementación en el .m pero no es lo habitual.



En el .h se definen todas las propiedades y métodos que queremos exponer públicamente, pero solo la firma y en el .m se define el comportamiento interno de la clase. Los métodos que son declarados en el fichro .h tenemos que implementarlos en el fichero .m.

Definición de las clases

C#

En C# las clases se definen asi:

//clase definida en del fichero ClaseEjemplo.cs
public class ClaseEjemplo 
{

}

Objetive-C

En Objetive-C las clases se definen entre su cabecera y su implementación.:

//Cabecera de la clase, fichero XURClaseEjemplo.h
@interface XURClaseEjemplo : NSObject
 
@end


La cabecera se define entre las directivas @interface y @end (las directivas de compilador en Objective-C están precedidas de @). Aquí en la cabecera es donde se debe indicar la clase base de la clase que creamos, como mínimo será NSObject. Aunque la directiva se llama @interface no tiene nada que ver con los interface que conocemos en C# que son abstracciónes o contratos que una clase debe implementar, aquí este concepto se conoce como protocolo, pero esta fuera del alcance de este artículo y lo veremos en futuros post.

//implementación de la clase, fichero XURClaseEjemplo.m
@implementation XURClaseEjemplo
 
@end


Propiedades

Una clase puede contener propiedades como en cualquier lenguaje orientado a objetos.

C#

En C# se definen así:

public class ClaseEjemplo 
{
    private string title;

    public string Title
    {
        //propiedad definida en la ClaseEjemplo.cs
        get
        {
            Return title
        }

        set
        {
            title = value;
        }
    }
}


Si queremos solo lectura o escritura basta con omitir el get o el set. También existe una versión simplificada donde el compilador genera la versión completa por nosotros y se define así:

public class ClaseEjemplo 
{
    public string Title { get; set; }
}


Objetive-C

En Objetive-C las propiedades se pueden definir en el fichero .h y en el .m, en el .h si van a ser consumidas públicamente y en el .m si son para uso interno en la implementación de la clase exclusivamente.

En Objetive-C existe una versión simplificada de crear propiedades igual que en C# y es utilizando la directiva @property. Este es un ejemplo:
    @property NSString *title;


Esta directiva transforma la propiedad en un getter y setter, por defecto el getter tiene el mismo nombre que la propiedad y el setter tiene el prefijo set y luego el nombre de la propiedad. Este comportamiento se puede modificar como veremos más a delante.

    - (NSString *) title;
    - (void) setTitle: (NSString *) newTitle;


Y también genera una variable de instancia con el nombre de la propiedad y con el prefijo de un subguión que se utilizará en los getter y setter.
Definición en cabecera
Las propiedades se pueden definir en el fichero .h cuando queremos exponerlas al consumidor

@interface XURClaseEjemplo : NSObject
    @property NSString *title;
@end
Definición en Implementacion
Las propiedades se pueden definir en el fichero .m cuando queremos que sean consumidas solo por la implementación interna de la clase. Para esto puede existir una sección @interface dentro del fichero de implementación además de la sección @implementation

@interface XURClaseEjemplo ()
    @property NSString *title;
@end
@implementation XURClaseEjemplo


@end
Atributos de propiedad
La directiva @property tiene unos atributos que le podemos asignar dentro de unos parentesis separados por comas a continuación de @property. Vamos a ver cada uno de estos atributos:
  • getter y setter, mediante este atributo podemos especificar el nombre que queremos que tenga el getter y/o el setter
                @property (getter=isNew) NSString *new;
            
  • atomic o nonatomic, atomic es el valor por defecto si no indicamos nada, atomic significa que solo se va a poder acceder a la propiedad desde un hilo. nonatmic permite acceder desde varios hilos y no garantiza el comportamiento que va a suceder al ser accedido desde varios hilos.
                @property (getter=isNew, nonatomic) NSString *new;
            
  • readonly o readwrite, readwrite es el valor por defecto si no indicamos nada, readwrite significa que la propiedad es de lectura y escritura, readonly indica que es de solo lectura.
            @property (getter=isNew, nonatomic, readonly) NSString *new;
        
  • strong, weak o assign,copy estos atributos tienen que ver con la gestion de la memoria. En IOS existe una caracteristica del compilador que se llama Automatic Reference Counting (ARC) que se encarga llevar la cuenta de las referencias a un objeto y de eliminar los objetos cuando ya no son necesarios al no quedar ninguna referencia, mediante estos atributos vamos a indicar como se debe gestionar la memoria para las referencias a objetos que se crean con las propiedades.
    strong es el valor por defecto para propiedades objetos, con este atributo indicamos que la propiedad es el dueño del objeto al que apunta el puntero, esto incrementa el número de referencias del objeto y no se liberará mientras el puntero siga activo. Weak es el caso contrarío, indicamos que la propiedad no es el dueño del objeto al que apunta el puntero y no incrementa el número de referencias que tiene. Assign es igual que weak pero la unica diferencia es que si el objeto al que se apunta es liberado, con weak el valor de la propiedad pasa a ser nil (null). Y finalmente copy lo que va a hacer es crear una copia del objeto, no utiliza el mismo y por tanto el número de referencias que apuntan a este nuevo objeto será 1.
            @property (strong, getter=isNew, nonatomic, readonly) NSString *new;
        

Libros relacionados

iOs Programming for .Net Developers

iOS Programming: The Big Nerd Ranch Guide

Objective-C Programming: The Big Nerd Ranch Guide

No hay comentarios:

Publicar un comentario