summaryrefslogtreecommitdiffhomepage
path: root/es-es/objective-c-es.html.markdown
diff options
context:
space:
mode:
authorLidenburg <richard.lindberg1997@gmail.com>2016-03-15 18:56:44 +0100
committerLidenburg <richard.lindberg1997@gmail.com>2016-03-15 18:56:44 +0100
commitce5183bd3d38094401ec37b691fb11c08ec3a07f (patch)
tree6227674189be0b6ae719f956c800de98daa4b283 /es-es/objective-c-es.html.markdown
parentc38933a4d187bb2f7a13b1716e9c6d884b390e89 (diff)
parent2095ad9cf5f3243296be5a7232dc52ae03603f49 (diff)
Merge remote-tracking branch 'refs/remotes/adambard/master'
Diffstat (limited to 'es-es/objective-c-es.html.markdown')
-rw-r--r--es-es/objective-c-es.html.markdown851
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)