diff options
Diffstat (limited to 'es-es/objective-c-es.html.markdown')
| -rw-r--r-- | es-es/objective-c-es.html.markdown | 851 | 
1 files changed, 851 insertions, 0 deletions
| diff --git a/es-es/objective-c-es.html.markdown b/es-es/objective-c-es.html.markdown new file mode 100644 index 00000000..bdbce524 --- /dev/null +++ b/es-es/objective-c-es.html.markdown @@ -0,0 +1,851 @@ +--- +language: Objective-C +contributors: +    - ["Eugene Yagrushkin", "www.about.me/yagrushkin"] +    - ["Yannick Loriot", "https://github.com/YannickL"] +    - ["Levi Bostian", "https://github.com/levibostian"] +translators: +    - ["David Hsieh", "http://github.com/deivuh"] +lang: es-es +filename: LearnObjectiveC-es.m +--- +Objective C es el lenguaje de programación principal utilizado por Apple para los sistemas operativos OS X y iOS y sus respectivos frameworks, Cocoa y Cocoa Touch. +Es un lenguaje de programación para propósito general que le agrega al lenguaje de programación C una mensajería estilo "Smalltalk". + + +```objective_c +// Los comentarios de una sola línea inician con // + +/* +Los comentarios de múltiples líneas se ven así. +*/ + +// Importa los encabezados de Foundation con #import +// Utiliza <> para importar archivos globales (generalmente frameworks) +// Utiliza "" para importar archivos locales (del proyecto) +#import <Foundation/Foundation.h> +#import "MyClass.h" + +// Si habilitas módulos para proyectos de iOS >= 7.0 u OS X >= 10.9 en +// Xcode 5, puedes importarlos de la siguiente manera: +@import Foundation; + +// El punto de entrada de tu programa es una función llamada  +// main con un tipo de retorno entero.  +int main (int argc, const char * argv[]) +{ +    // Crear un autorelease pool para manejar la memoria al programa +    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; +    // Si se utiliza el conteo automático de referencias (ARC),  +    // utiliza @autoreleasepool:     +    @autoreleasepool { + +    // Utiliza NSLog para imprimir líneas a la consola +    NSLog(@"Hello World!"); // Imprimir el string "Hello World!" +  +    /////////////////////////////////////// +    // Tipos y variables +    /////////////////////////////////////// +     +    // Declaraciones de primitivos +    int myPrimitive1  = 1; +    long myPrimitive2 = 234554664565; +     +    // Declaraciones de objetos +    // Pon el * como prefijo de los nombre de las variables para declaraciones +    // de objetos de tipos fuertes  +    MyClass *myObject1 = nil;  // Tipo fuerte +    id       myObject2 = nil;  // Tipo débil +    // %@ es un objeto +    // 'description' es una convención para mostrar el valor de los objetos +    NSLog(@"%@ and %@", myObject1, [myObject2 description]);  +    // imprime => "(null) and (null)" +     +    // String +    NSString *worldString = @"World"; +    NSLog(@"Hello %@!", worldString); // imprime => "Hello World!"  +    // NSMutableString es una versión mutable del objeto NSString +    NSMutableString *mutableString = [NSMutableString stringWithString:@"Hello"]; +    [mutableString appendString:@" World!"]; +    NSLog(@"%@", mutableString); // imprime => "Hello World!" +     +    // Literales de caracteres +    NSNumber *theLetterZNumber = @'Z'; +    char theLetterZ            = [theLetterZNumber charValue]; // o 'Z' +    NSLog(@"%c", theLetterZ); + +    // Literales de enteros +    NSNumber *fortyTwoNumber = @42; +    int fortyTwo             = [fortyTwoNumber intValue]; // o 42 +    NSLog(@"%i", fortyTwo); +     +    NSNumber *fortyTwoUnsignedNumber = @42U; +    unsigned int fortyTwoUnsigned    = [fortyTwoUnsignedNumber unsignedIntValue]; // o 42 +    NSLog(@"%u", fortyTwoUnsigned); +     +    NSNumber *fortyTwoShortNumber = [NSNumber numberWithShort:42]; +    short fortyTwoShort           = [fortyTwoShortNumber shortValue]; // o 42 +    NSLog(@"%hi", fortyTwoShort); + +    NSNumber *fortyOneShortNumber   = [NSNumber numberWithShort:41]; +    unsigned short fortyOneUnsigned = [fortyOneShortNumber unsignedShortValue]; // o 41 +    NSLog(@"%u", fortyOneUnsigned); +     +    NSNumber *fortyTwoLongNumber = @42L; +    long fortyTwoLong            = [fortyTwoLongNumber longValue]; // o 42 +    NSLog(@"%li", fortyTwoLong); + +    NSNumber *fiftyThreeLongNumber   = @53L; +    unsigned long fiftyThreeUnsigned = [fiftyThreeLongNumber unsignedLongValue]; // o 53 +    NSLog(@"%lu", fiftyThreeUnsigned); + +    // Literales de punto flotante +    NSNumber *piFloatNumber = @3.141592654F; +    float piFloat           = [piFloatNumber floatValue]; // o 3.141592654f +    NSLog(@"%f", piFloat); // imprime => 3.141592654 +    NSLog(@"%5.2f", piFloat); // imprime => " 3.14" +     +    NSNumber *piDoubleNumber = @3.1415926535; +    double piDouble          = [piDoubleNumber doubleValue]; // o 3.1415926535 +    NSLog(@"%f", piDouble); +    NSLog(@"%4.2f", piDouble); // imprime => "3.14" + +    // NSDecimalNumber es una clase de punto-fijo que es más preciso que float o double     +    NSDecimalNumber *oneDecNum = [NSDecimalNumber decimalNumberWithString:@"10.99"]; +    NSDecimalNumber *twoDecNum = [NSDecimalNumber decimalNumberWithString:@"5.002"]; +    // NSDecimalNumber no tiene la capacidad de utilizar los operadores estándares  +    // +, -, * , /, por lo que cuenta con sus propios operadores:     +    [oneDecNum decimalNumberByAdding:twoDecNum];  +    [oneDecNum decimalNumberBySubtracting:twoDecNum]; +    [oneDecNum decimalNumberByMultiplyingBy:twoDecNum]; +    [oneDecNum decimalNumberByDividingBy:twoDecNum]; +    NSLog(@"%@", oneDecNum); // imprime => 10.99 como NSDecimalNumber es inmutable + +    // Literales BOOL +    NSNumber *yesNumber = @YES; +    NSNumber *noNumber  = @NO; +    // o +    BOOL yesBool = YES; +    BOOL noBool  = NO; +    NSLog(@"%i", yesBool); // prints => 1 + +    // Objecto arreglo +    // Puede contener diferentes tipos de datos, pero deben de ser un objeto de +    // Objective-C     +    NSArray *anArray      = @[@1, @2, @3, @4]; +    NSNumber *thirdNumber = anArray[2]; +    NSLog(@"Third number = %@", thirdNumber); // imprime => "Third number = 3" +    // NSMutableArray es una versión mutable de NSArray, permitiendo el cambio +    // de los elementos del arreglo y el agrandado o encojimiento del objeto arreglo. +    // Conveniente, pero no tan eficiente como NSArray en cuanto a rendimiento.  +    NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:2]; +    [mutableArray addObject:@"Hello"]; +    [mutableArray addObject:@"World"]; +    [mutableArray removeObjectAtIndex:0]; +    NSLog(@"%@", [mutableArray objectAtIndex:0]); // imprime => "World" + +    // Objecto Diccionario +    NSDictionary *aDictionary = @{ @"key1" : @"value1", @"key2" : @"value2" }; +    NSObject *valueObject     = aDictionary[@"A Key"]; +    NSLog(@"Object = %@", valueObject); // imprime => "Object = (null)" +    // NSMutableDictionary también está disponible como un objeto mutable +    NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithCapacity:2]; +    [mutableDictionary setObject:@"value1" forKey:@"key1"]; +    [mutableDictionary setObject:@"value2" forKey:@"key2"]; +    [mutableDictionary removeObjectForKey:@"key1"]; + +    // Objeto de Set +    NSSet *set = [NSSet setWithObjects:@"Hello", @"Hello", @"World", nil]; +    NSLog(@"%@", set); // imprime => {(Hello, World)} (el orden puede variar) +    // NSMutableSet también está disponible como un objeto mutable +    NSMutableSet *mutableSet = [NSMutableSet setWithCapacity:2]; +    [mutableSet addObject:@"Hello"]; +    [mutableSet addObject:@"Hello"]; +    NSLog(@"%@", mutableSet); // prints => {(Hello)} + +    /////////////////////////////////////// +    // Operadores +    /////////////////////////////////////// +     +    // Los operadores funcionan como en el lenguaje C +    // Por ejemplo: +    2 + 5; // => 7 +    4.2f + 5.1f; // => 9.3f +    3 == 2; // => 0 (NO) +    3 != 2; // => 1 (YES) +    1 && 1; // => 1 (and lógico) +    0 || 1; // => 1 (or lógico) +    ~0x0F; // => 0xF0 (negación bitwise) +    0x0F & 0xF0; // => 0x00 (AND bitwise) +    0x01 << 1; // => 0x02 (acarreamiento a la izquierda bitwise (por 1)) + +    /////////////////////////////////////// +    // Estructuras de control +    /////////////////////////////////////// + +    // Declaraciones If-Else +    if (NO) +    { +        NSLog(@"I am never run"); +    } else if (0) +    { +        NSLog(@"I am also never run"); +    } else +    { +        NSLog(@"I print"); +    } + +    // Declaración Switch +    switch (2) +    { +        case 0: +        { +            NSLog(@"I am never run"); +        } break; +        case 1: +        { +            NSLog(@"I am also never run"); +        } break; +        default: +        { +            NSLog(@"I print"); +        } break; +    } +     +    // Declaración de ciclos While +    int ii = 0; +    while (ii < 4) +    { +        NSLog(@"%d,", ii++); // ii++ incrementa ii en la misma línea, luego de  +                             // utilizar su valor +    } // imprime => "0,"  +      //           "1," +      //           "2," +      //           "3," + +    // Declaración de ciclos For +    int jj; +    for (jj=0; jj < 4; jj++) +    { +        NSLog(@"%d,", jj); +    } // imprime => "0,"  +      //           "1," +      //           "2," +      //           "3," +      +    // Declaraciones foreach +    NSArray *values = @[@0, @1, @2, @3]; +    for (NSNumber *value in values) +    { +        NSLog(@"%@,", value); +    } // imprime => "0,"  +      //           "1," +      //           "2," +      //           "3," + +    // Objeto de ciclos For. Puede ser utilizado con cualquier tipo de objecto de  +    // Objective-C +    for (id item in values) {  +        NSLog(@"%@,", item);  +    } // imprime => "0,"  +      //           "1," +      //           "2," +      //           "3," + +    // Declaraciones Try-Catch-Finally +    @try +    { +        // Tus declaraciones aquí +        @throw [NSException exceptionWithName:@"FileNotFoundException" +                            reason:@"File Not Found on System" userInfo:nil]; +    } @catch (NSException * e) // utiliza: @catch (id exceptionName) para atrapar  +                               // todos los objetos +    { +        NSLog(@"Exception: %@", e); +    } @finally +    { +        NSLog(@"Finally. Time to clean up."); +    } // imprime => "Exception: File Not Found on System" +      //           "Finally. Time to clean up." + +    // Los objetos NSError son útiles para argumentos de función para los  +    // errores de usuario.     +    NSError *error = [NSError errorWithDomain:@"Invalid email." code:4 userInfo:nil]; +  +    /////////////////////////////////////// +    // Objetos +    /////////////////////////////////////// +     +    // Crea una instancia de objeto alocando memoria e inicializándola +    // Un objeto no es completamente funcional hasta que ambos pasos hayan sido +    // completados +    MyClass *myObject = [[MyClass alloc] init]; +         +    // El modelo de programación orientada a objetos de Objective-C es basada en +    // el envío de mensajes a instancias de objetos +    // En Objective-C no se llama a un método; se envía un mensaje     +    [myObject instanceMethodWithParameter:@"Steve Jobs"]; + +    // Limpiar la memoria que se utilizó en el programa     +    [pool drain]; + +    // Fin de @autoreleasepool +    } +     +    // Fin del programa +    return 0; +} + +/////////////////////////////////////// +// Clases y funciones +/////////////////////////////////////// + +// Declara tu clase en archivo de encabezado (MyClass.h) +// Sintaxis de declaración de clase: +// @interface NombreDeClase : NombreDeClasePadre <ProtocolosImplementados> +// { +//    type nombre; <= declaraciones de variables; +// } +// @property tipo nombre; <= declaración de propiedades +// -/+ (tipo) Declaración de método; <= Declaración de método +// @end +@interface MyClass : NSObject <MyProtocol> // NSObject es la clase de objeto  +                                           // base de  Objective-C. +{ +    // Declaraciones de variables de instancia (puede existir en el archivo de  +    // interfaz o de implementación)     +    int count; // Acceso protegido por defecto.  +    @private id data; // Acceso privado (Más conveniente de declarar en el  +                      // archivo de implementación) +    NSString *name;  +} +// Notación conveneinte para acceso público de las variables para generar un  +// método setter +// Por defecto, el nombre del método setter 'set' seguido del nombre de  +// variable @property +@property int propInt; // Nombre del método 'setter' = 'setPropInt' +@property (copy) id copyId; // (copy) => Copia el objeto durante la asignación +// (readonly) => No se le puede asignar un valor fuera de @interface +@property (readonly) NSString *roString; // utiliza @synthesize en  +                                         // @implementation para crear un accesor +// Puedes personalizar el nombre del getter y del setter en lugar de utilizar +// el nombre por defecto "set". +@property (getter=lengthGet, setter=lengthSet:) int length; +  +// Métodos ++/- (return type)methodSignature:(Parameter Type *)parameterName; + +// + Para métodos de clase: ++ (NSString *)classMethod; ++ (MyClass *)myClassFromHeight:(NSNumber *)defaultHeight; + +// - Para métodos de instancia: +- (NSString *)instanceMethodWithParameter:(NSString *)string; +- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number; + +// Métodos de constructor con argumentos +- (id)initWithDistance:(int)defaultDistance; +// Los nombres de los métodos de Objective-C son muy descriptivos.  +// Siempre nombra los métodos de acuerdo con sus argumentos + +@end // Define el final de la interfaz + + +// Para acceder a las variables públicas desde el archivo de implementación,  +// @property genera un método setter automáticamente. El nombre del método  +// es 'set' seguido de un nombre de variable @property: +MyClass *myClass = [[MyClass alloc] init]; // Crea una instancia del objeto MyClass  +[myClass setCount:10];  +NSLog(@"%d", [myClass count]); // imprime => 10 +// O utilizando los métodos getter y setter personalizados en @interface: +[myClass lengthSet:32]; +NSLog(@"%i", [myClass lengthGet]); // imprime => 32 +// Por conveniencia, puedes utilizar la notación de punto para asignar y  +// acceder a las variables de una instancia de objeto. +myClass.count = 45; +NSLog(@"%i", myClass.count); // imprime => 45 + +// Llama a métodos de clase: +NSString *classMethodString = [MyClass classMethod]; +MyClass *classFromName = [MyClass myClassFromName:@"Hello"]; + +// Llama a métodos de instancia: +MyClass *myClass = [[MyClass alloc] init]; // Crea una instancia de objeto Myclass +NSString *stringFromInstanceMethod = [myClass instanceMethodWithParameter:@"Hello"]; + +// Selectors +// Una forma dinámica de representar métodos. Utilizados para llamar métodos  +// de una clase, pasar métodos a través de funciones para avisar a otras clases  +// para que lo llamen, y para guardar métodos como una variable. +// SEL es el tipo de dato. @selector() devuelve un selector del nombre de  +// método proveído methodAparameterAsString:andAParameterAsNumber: es un nombre  +// para un método en MyClass +SEL selectorVar = @selector(methodAParameterAsString:andAParameterAsNumber:);  +if ([myClass respondsToSelector:selectorVar]) { // Revisa si la clase contiene el método +    // Debe de poner todos los argumentos de método en un solo objeto para mandar una  +    // función performSelector.     +    NSArray *arguments = [NSArray arrayWithObjects:@"Hello", @4, nil]; +    [myClass performSelector:selectorVar withObject:arguments]; // Calls the method +} else { +    // NSStringFromSelector() devuelve un NSString del nombre de método de un selector dado +    NSLog(@"MyClass does not have method: %@", NSStringFromSelector(selectedVar)); +} + +// Implementa los métodos de un archivo de implementación (MyClass.m): +@implementation MyClass { +    long distance; // Variable de instancia de acceso privado +    NSNumber height; +} + +// Para acceder a una variable pública del archivo de interfaz, utiliza '_' seguido del +// nombre de la variable: +_count = 5; // Hace referencia a "int count" de la interfaz de MyClass +// Accede variables definidas en el archivo de implementación: +distance = 18; // Hace referencia a "long distance" de la implementación de MyClass +// Para utilizar una variable @property en el archivo de implementación, utiliza  +// @synthesize para crear una variable de acceso: +@synthesize roString = _roString; // _roString ahora está disponible en @implementation + +// Lamado antes de llamar algún método o instanciar cualquier objeto ++ (void)initialize  +{ +    if (self == [MyClass class]) { +        distance = 0; +    } +} + +// Contraparte para inicializar un método. Llamado cuando el contador de referencias +// del objeto es cero +- (void)dealloc +{ +    [height release]; // Si no utilizas ARC, asegúrate de liberar las variables de  +                      // objeto de las clases +    [super dealloc];  // y llama el método dealloc de la clase padre +} + +// Los constructores son una manera de crear instancias de una clase +// Este es el constructor por defecto que es llamado cuando el objeto es inicializado. +- (id)init +{ +    if ((self = [super init])) // 'super' es utilizado para acceder a los  +                               // métodos de la clase padre. +    { +        self.count = 1; // 'self' es utilizado para que el objeto se llame a sí mismo. +    } +    return self; +} +// Se pueden crear constructores que contiene argumentos +- (id)initWithDistance:(int)defaultDistance  +{ +    distance = defaultDistance; +    return self; +} + ++ (NSString *)classMethod +{ +    return @"Some string"; +} + ++ (MyClass *)myClassFromHeight:(NSNumber *)defaultHeight  +{ +    height = defaultHeight; +    return [[self alloc] init]; +} + +- (NSString *)instanceMethodWithParameter:(NSString *)string +{ +    return @"New string"; +} + +- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number +{ +    return @42; +} + +// Objective-C no tiene declaraciones de métodos privados, pero pueden ser simulados. +// Para simular un método privado, crea un método en @implementation pero no en @interface. +- (NSNumber *)secretPrivateMethod { +    return @72; +} +[self secretPrivateMethod]; // Calls private method + +// Métodos declarados dentro de MyProtocol +- (void)myProtocolMethod +{ +    // statements +} + +@end // Declara el final de la implementación + +/////////////////////////////////////// +// Categorías +/////////////////////////////////////// +// Una categoría es un grupo de métodos diseñados para extender una clase.  +// Te permiten agregar nuevos métodos a una clase existente por propósitos  +// de organización. Éstos no deben de serconfundidos con subclases.  +// Las subclases existen para CAMBIAR la funcionalidad de un objeto mientras  +// que las categoríasle AGREGAN funcionalidad de un objeto. +// Las categorías te permiten: +// -- Agregar métodos a una clase existente por propósitos de oganización. +// -- Extender clases de objetos de Objective-C (ejemplo: NSString) para  +//    agregar tus propios métodos. +// -- Agregar la habilidad de crear métodos protegidos y privados para las clases. +// NOTA: No sobreescribas los métodos de las clases base en una categoría  +// aunque tengas la habilidad de poder hacerlo. Sobreescribir métodos puede  +// causar errores en la compilación después entre diferentes categorías y  +// puede arruinar el propósito de las categorías de solo AGREGAR funcionalidad.  +// Utiliza subclass para sobreescribir métodos. + +// Aquí una clase base simple, Car. +@interface Car : NSObject + +@property NSString *make; +@property NSString *color; + +- (void)turnOn; +- (void)accelerate; + +@end + +// Y la implementación de la clase simple, Car +#import "Car.h" + +@implementation Car + +@synthesize make = _make; +@synthesize color = _color; + +- (void)turnOn { +    NSLog(@"Car is on."); +} +- (void)accelerate { +    NSLog(@"Accelerating."); +} + +@end + +// Ahora, si quisieramos crear un objeto Truck (Camión), crearíamos una  +// subclase de Car (Carro) como si le cambiaramos de funcionalidad de Car  +// para que se comporte como un camión. Pero digamos que únicamente queremos  +// agregar funcionalidad al Car (Carro) existente. Un buen ejemplo sería  +// limpiar el carro. Así que crearíamos una cateog®iea para agregar los  +// métodos de limpieza:  +// Archivo @interface: Car+Clean.h (NombreBaseDeClase+NombreDeCategoria.h) +#import "Car.h" // Asegúrate de improtar la clase que deseas extener. + +@interface Car (Clean) // El nombre de la categoría está dentro de (),  +                       // seguido del nombre de la clase base + +- (void)washWindows; // Nombres de los nuevos métodos que le agregamos  +                     // a nuestro objeto Car +- (void)wax; + +@end + +// Archivo @implementation: Car+Clean.m (NombreBaseDeClase+NombreDeCategoria.m) +#import "Car+Clean.h" // Importa el archivo de @interface de la categoría Clean + +@implementation Car (Clean) + +- (void)washWindows { +    NSLog(@"Windows washed."); +} +- (void)wax { +    NSLog(@"Waxed."); +} + +@end  + +// Cualquier instancia del objeto Car tiene la habilidad de utilizar una  +// categoría. Todo lo que necesitan es importarlo:  +#import "Car+Clean.h" // Importa todas las diferentes categorías que  +                      // necesites utilizar +#import "Car.h" // También debes de importar la clase base para su  +                // funcionalidad original  + +int main (int argc, const char * argv[]) { +    @autoreleasepool { +        Car *mustang = [[Car alloc] init]; +        mustang.color = @"Red"; +        mustang.make = @"Ford"; + +        [mustang turnOn]; // Utiliza métodos de la clase base Car. +        [mustang washWindows]; // Utiliza métodos de la categoría Clean de Car. +    } +    return 0;  +} + +// Objective-C no tiene declaraciones para métodos protegidos, pero los puedes +// simular. Crea una categoría conteniendo todos los métodos protegidos,  +// luego importa ÚNICAMENTE al archivo @implementation de una clase que  +// pertenece a la clase Car. +@interface Car (Protected) // Nombrando la categoría 'Protected' para  +                           // recordar que los métodos están protegidos +     +- (void)lockCar; // Los métodos enlistados aquí solo puedens ser creados  +                 // por objetos Car + +@end +// Para utilizar los métodos protegidos, importa la categoría,  +// luego implementa sus métodos: +#import "Car+Protected.h" // Recuerda, importa únicamente el archivo  +                          // de @implementation + +@implementation Car  + +- (void)lockCar { +    NSLog(@"Car locked."); // Las instancias de Car no puede utilizar  +                           // lockCar porque no se encuentra en @interface +} + +@end + +/////////////////////////////////////// +// Extensiones +/////////////////////////////////////// +// Las Extensions te permiten sobreescribir atributos de propiedades de  +// acceso público y métodos de un @interface +// Archivo @interface: Shape.h +@interface Shape : NSObject  + +@property (readonly) NSNumber *numOfSides; + +- (int)getNumOfSides; + +@end +// Puedes sobreescribir la variable numOfSides o el métodos getNumOfSlides  +// para modificarlos con una extensión: +// Archivo @implementation: Shape.m +#import "Shape.h" +// Las extensiones se encuentran en el mismo archivo que el archivo  +// de @implementation +@interface Shape () // () después del nombre de la clase base declara  +                    // una extensión + +@property (copy) NSNumber *numOfSides; // Hacer numOfSlides copy en lugar +                                       // de readonly. +-(NSNumber)getNumOfSides; // Hacer que getNumOfSides devuelva un NSNumber  +                          // en lugar de un int. +-(void)privateMethod; // También puedes crear una nuevos métodos privados  +                      // dentro de las extensiones + +@end +// @implementation principal: +@implementation Shape  + +@synthesize numOfSides = _numOfSides; + +-(NSNumber)getNumOfSides { // Todas las declaraciones dentro de extensions  +                           // deben de ser dentro de @implementation +    return _numOfSides; +} +-(void)privateMethod { +    NSLog(@"Private method created by extension. Shape instances cannot call me."); +} + +@end + +/////////////////////////////////////// +// Protocolos +/////////////////////////////////////// +// Un protocolo declara métodos que pueden ser implementados por cualquier otra +// clase. Los protocolos no son clases. Simplementen define una interfaz que  +// otros objetos deben de implementar. +// Archivo @protocol: "CarUtilities.h" +@protocol CarUtilities <NSObject> // <NSObject> => Nombre de otro protocolo  +                                  // que se incluye en éste +    @property BOOL engineOn; // La clase que lo adopta debe de utilizar  +                            // @synthesize para todas las @properties definidas  +    - (void)turnOnEngine; // y todos los métodos definidos +@end +// A continuación una clase ejemplo que implementa el protcolo +#import "CarUtilities.h" // Importar el archivo @protocol. + +@interface Car : NSObject <CarUtilities> // El nombre del protocolo dentro de <> +    // No necesitas los nombres de @property o métodos aquí para CarUtilities. +    // Estos solo es requerido por @implementation. +- (void)turnOnEngineWithUtilities:(id <CarUtilities>)car; // También Puedes  +                                                          // utilizar protocolos  +                                                          // como datos. +@end +// El @implementation necesita que se implementen @properties y métodos  +// del protocolo. +@implementation Car : NSObject <CarUtilities> + +@synthesize engineOn = _engineOn; // Crear una declaración @synthesize para el  +                                  // @property engineOn. + +- (void)turnOnEngine { // Implementa turnOnEngine como quieras. Los  +                       // protocolos no definen +    _engineOn = YES;   // cómo implementas un método, con tal de que lo implementes. +} +// Puedes utilizar un protocolo como data mientras sepas quee métodos y variables  +// tiene implementado. +- (void)turnOnEngineWithCarUtilities:(id <CarUtilities>)objectOfSomeKind {  +    [objectOfSomeKind engineOn]; // Tienes acceso a las variables  +    [objectOfSomeKind turnOnEngine]; // y los métodos del objeto +    [objectOfSomeKind engineOn]; // Puede o no puede ser YES. La clase lo  +                                 // implementa como se quiera. +} + +@end +// Las instancias de Car ahora tienen acceso al protocolo. +Car *carInstance = [[Car alloc] init]; +[carInstance setEngineOn:NO]; +[carInstance turnOnEngine]; +if ([carInstance engineOn]) { +    NSLog(@"Car engine is on."); // imprime => "Car engine is on." +} +// Asegúrate de revisar si un objeto de tipo 'id' implementa un protocolo antes +// de llamar a sus métodos: +if ([myClass conformsToProtocol:@protocol(CarUtilities)]) { +    NSLog(@"This does not run as the MyClass class does not implement the CarUtilities protocol."); +} else if ([carInstance conformsToProtocol:@protocol(CarUtilities)]) { +    NSLog(@"This does run as the Car class implements the CarUtilities protocol."); +} +// Las categorías también pueden implementar protcolos: @interface Car  +// (CarCategory) <CarUtilities> +// Puedes implementar varios protocolos:  +// @interface Car : NSObject <CarUtilities, CarCleaning> +// NOTA: Si dos o más protocolos dependen entre sí, asegúrate de declararlos  +// de manera adelantada: +#import "Brother.h" + +@protocol Brother; // Declaración adelantada. Sin ésto, el compilador  +                   // tira un error. + +@protocol Sister <NSObject> + +- (void)beNiceToBrother:(id <Brother>)brother; + +@end + +// Ver si el problema es que Sister depende de Brother,  +// y Brother dependa de Sister. +#import "Sister.h" + +@protocol Sister; // Estas líneas detienen la recursión, resolviendo el problema. + +@protocol Brother <NSObject> +  +- (void)beNiceToSister:(id <Sister>)sister; + +@end + + +/////////////////////////////////////// +// Bloques +/////////////////////////////////////// +// Los bloques son declaraciones de código, tal como una función, pueden  +// ser utilizados como data. +// A continuación un bloque simple con un argumento entero que devuelve  +// un el argumento más 4. +int (^addUp)(int n); // Declarar una variable para almacenar el bloque. +void (^noParameterBlockVar)(void); // Ejemplo de una declaración de variable  +                                   // de bloque sin argumentos. +// Los bloques tienen acceso a variables del mismo ámbito. Pero las variables  +// son solo readonly y el valor pasado al bloque es el valor de la variable  +// cuando el bloque es creado. +int outsideVar = 17; // Si modificamos outsideVar después de declarar addUp, +                     // outsideVar AÚN es 17. +__block long mutableVar = 3; // __block hace que las variables se puedan  +                             // escribir en bloques. +addUp = ^(int n) { // Remueve (int n) para tener un bloque que no recibe  +                   // ningún parámetro +    NSLog(@"You may have as many lines in a block as you would like."); +    NSSet *blockSet; // También puedes declarar variables locales. +    mutableVar = 32; // Asignar un nuevo valor a la variable __block. +    return n + outsideVar; // Declaraciones de retorno son opcionales. +} +int addUp = add(10 + 16); // Llama al bloque de código con argumentos. +// Los bloques son usualmente utilizados como argumentos a funciones que  +// son llamados más adelante o para callbacks. +@implementation BlockExample : NSObject  +  + - (void)runBlock:(void (^)(NSString))block { +    NSLog(@"Block argument returns nothing and takes in a NSString object."); +    block(@"Argument given to block to execute."); // Calling block. + } + + @end + + +/////////////////////////////////////// +// Manejo de memoria +/////////////////////////////////////// +/*  +Para cada objeto utilizado en una aplicación, la memoria debe de ser alocada  +para ese objeto. Cuando la aplicación termina de utilizar ese objeto, la  +memoria debe de ser desalocada para asegurar la  eficiencia de la aplicación. +Objetive-C no utiliza garbage collection, y en lugar de eso utiliza conteos  +de referencias. Mientras haya al menos una referencia del objeto (también  +conocido como tener un objeto de adueñado), entonces el objeto estará  +disponible para su uso. + +Cuando una instancia es dueña un objeto, su contador de referencia incrementa +por uno. Cuando el objeto es liberado, el contador de referencia decrementa uno.  +Cuando el conteo de referencia es cero, el objeto es removido de la memoria. + +Con todas las interacciones de los objetos, sigue el patrón de: +(1) Crear e lobjeto, (2) utiliza el objeto, (3) libera el objeto de la memoria. +*/ + +MyClass *classVar = [MyClass alloc]; // 'alloc' asigna uno al conteo de  +                                     // referencias de classVar. Devuelve un  +                                     // puntero al objeto +[classVar release]; // Decrementa el conteo de referencias de classVar's +// 'retain' +// 'retain' adueña la instancia de objeto existente e incrementa el conteo de  +// referencia por uno. Devuelve un puntero al objeto. +MyClass *newVar = [classVar retain]; // Si classVar es liberado, el objeto  +                                     // aún se queda en memoria porque newVar +                                     // es el dueño. +[classVar autorelease]; // Remueve el adueñamiento de un objeto al final del  +                        // bloque @autoreleasepool. Devuelve un puntero al objeto. + +// @property puede utilizar 'retain' y 'assign' también para pequeñas  +// definiciones convenientes +@property (retain) MyClass *instance; // Libera el valor viejo y retiene  +                                      // uno nuevo (referencia fuerte) +@property (assign) NSSet *set; // Apunta a un nuevo valor sin retener/liberar  +                               // una referencia vieja (débil) + +// Conteo Automático de Referencias (ARC) +// Debido a que el manejo de memoria puede ser un dolor, en Xcode 4.2 y iOS 4  +// se introdujo el Conteo Automático de Referencias (ARC). +// ARC es una funcionalidad del compilador que agrega retain, release y +// autorealase automáticamente, así que al +// utilizar ARC, no se debe de utilizar retain, release o autorelease. +MyClass *arcMyClass = [[MyClass alloc] init];  +// ... código utilizando arcMyClass +// Sin ARC, necesitarás llamar: [arcMyClass release] luego de terminar de  +// utilizar arcMyClass. Pero con ARC, no hay necesidad. Insertará  +// automáticamente la declaración de liberación. + +// Mientras que para los atributos de @property 'assign' y 'retain', con ARC  +// utilizarás 'weak' y 'strong' +@property (weak) MyClass *weakVar; // 'weak' no adueña el objeto. El conteo de  +                                   // referencias de la instancia original +// es fijado a ceor, weakVar automáticamente recibe el valor de  nil para  +// evitar cualquier 'crashing'. +@property (strong) MyClass *strongVar; // 'strong' se adueña del objeto.  +                                       // Asegura que el objeto se quede en memoria. + +// Para variables regulares (no variables de @property), utiliza lo siguiente: +__strong NSString *strongString; // Por defecto. La variables de retenida en  +                                 // memoria hasta que se salga del ámbito. +__weak NSSet *weakSet; // Referencia débil a un objeto existente. Cuando el  +                       // objeto existente es liberado, weakSet le es asginado +                       // un valor nil +__unsafe_unretained NSArray *unsafeArray; // Como __weak, pero unsafeArray no  +                                          // es asginado a nil cuando el objeto +                                          // existente es liberado. + +``` +## Lecturas sugeridas + +[Wikipedia Objective-C](http://es.wikipedia.org/wiki/Objective-C) + +[Programming with Objective-C. Libro PDF de Apple](https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/ProgrammingWithObjectiveC.pdf) + +[iOS For High School Students: Getting Started](http://www.raywenderlich.com/5600/ios-for-high-school-students-getting-started) | 
