mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2024-12-26 00:31:39 +03:00
Reduced line lengths larger than 80 characters
This commit is contained in:
parent
6c0652bc9c
commit
6616ee7156
@ -38,7 +38,8 @@ int main (int argc, const char * argv[])
|
|||||||
{
|
{
|
||||||
// Crear un autorelease pool para manejar la memoria al programa
|
// Crear un autorelease pool para manejar la memoria al programa
|
||||||
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
||||||
// Si se utiliza el conteo automático de referencias (ARC), utiliza @autoreleasepool:
|
// Si se utiliza el conteo automático de referencias (ARC),
|
||||||
|
// utiliza @autoreleasepool:
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
|
|
||||||
// Utiliza NSLog para imprimir líneas a la consola
|
// Utiliza NSLog para imprimir líneas a la consola
|
||||||
@ -53,13 +54,14 @@ int main (int argc, const char * argv[])
|
|||||||
long myPrimitive2 = 234554664565;
|
long myPrimitive2 = 234554664565;
|
||||||
|
|
||||||
// Declaraciones de objetos
|
// Declaraciones de objetos
|
||||||
// Pon el * como prefijo de los nombre de las variables para declaraciones de
|
// Pon el * como prefijo de los nombre de las variables para declaraciones
|
||||||
// objetos de tipos fuertes
|
// de objetos de tipos fuertes
|
||||||
MyClass *myObject1 = nil; // Tipo fuerte
|
MyClass *myObject1 = nil; // Tipo fuerte
|
||||||
id myObject2 = nil; // Tipo débil
|
id myObject2 = nil; // Tipo débil
|
||||||
// %@ es un objeto
|
// %@ es un objeto
|
||||||
// 'description' es una convención para mostrar el valor de los objetos
|
// 'description' es una convención para mostrar el valor de los objetos
|
||||||
NSLog(@"%@ and %@", myObject1, [myObject2 description]); // imprime => "(null) y (null)"
|
NSLog(@"%@ and %@", myObject1, [myObject2 description]);
|
||||||
|
// imprime => "(null) and (null)"
|
||||||
|
|
||||||
// String
|
// String
|
||||||
NSString *worldString = @"World";
|
NSString *worldString = @"World";
|
||||||
@ -216,7 +218,8 @@ int main (int argc, const char * argv[])
|
|||||||
int ii = 0;
|
int ii = 0;
|
||||||
while (ii < 4)
|
while (ii < 4)
|
||||||
{
|
{
|
||||||
NSLog(@"%d,", ii++); // ii++ incrementa ii en la misma línea, luego de utilizar su valor
|
NSLog(@"%d,", ii++); // ii++ incrementa ii en la misma línea, luego de
|
||||||
|
// utilizar su valor
|
||||||
} // imprime => "0,"
|
} // imprime => "0,"
|
||||||
// "1,"
|
// "1,"
|
||||||
// "2,"
|
// "2,"
|
||||||
@ -242,7 +245,8 @@ int main (int argc, const char * argv[])
|
|||||||
// "2,"
|
// "2,"
|
||||||
// "3,"
|
// "3,"
|
||||||
|
|
||||||
// Objeto de ciclos For. Puede ser utilizado con cualquier tipo de objecto de Objective-C
|
// Objeto de ciclos For. Puede ser utilizado con cualquier tipo de objecto de
|
||||||
|
// Objective-C
|
||||||
for (id item in values) {
|
for (id item in values) {
|
||||||
NSLog(@"%@,", item);
|
NSLog(@"%@,", item);
|
||||||
} // imprime => "0,"
|
} // imprime => "0,"
|
||||||
@ -256,7 +260,8 @@ int main (int argc, const char * argv[])
|
|||||||
// Tus declaraciones aquí
|
// Tus declaraciones aquí
|
||||||
@throw [NSException exceptionWithName:@"FileNotFoundException"
|
@throw [NSException exceptionWithName:@"FileNotFoundException"
|
||||||
reason:@"File Not Found on System" userInfo:nil];
|
reason:@"File Not Found on System" userInfo:nil];
|
||||||
} @catch (NSException * e) // utiliza: @catch (id exceptionName) para atrapar todos los objetos
|
} @catch (NSException * e) // utiliza: @catch (id exceptionName) para atrapar
|
||||||
|
// todos los objetos
|
||||||
{
|
{
|
||||||
NSLog(@"Exception: %@", e);
|
NSLog(@"Exception: %@", e);
|
||||||
} @finally
|
} @finally
|
||||||
@ -265,7 +270,8 @@ int main (int argc, const char * argv[])
|
|||||||
} // imprime => "Exception: File Not Found on System"
|
} // imprime => "Exception: File Not Found on System"
|
||||||
// "Finally. Time to clean up."
|
// "Finally. Time to clean up."
|
||||||
|
|
||||||
// Los objetos NSError son útiles para argumentos de función para los errores de usuario.
|
// 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];
|
NSError *error = [NSError errorWithDomain:@"Invalid email." code:4 userInfo:nil];
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
@ -305,20 +311,27 @@ int main (int argc, const char * argv[])
|
|||||||
// @property tipo nombre; <= declaración de propiedades
|
// @property tipo nombre; <= declaración de propiedades
|
||||||
// -/+ (tipo) Declaración de método; <= Declaración de método
|
// -/+ (tipo) Declaración de método; <= Declaración de método
|
||||||
// @end
|
// @end
|
||||||
@interface MyClass : NSObject <MyProtocol> // NSObject es la clase de objeto base de Objective-C.
|
@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)
|
// Declaraciones de variables de instancia (puede existir en el archivo de
|
||||||
|
// interfaz o de implementación)
|
||||||
int count; // Acceso protegido por defecto.
|
int count; // Acceso protegido por defecto.
|
||||||
@private id data; // Acceso privado (Más conveniente de declarar en el archivo de implementación)
|
@private id data; // Acceso privado (Más conveniente de declarar en el
|
||||||
|
// archivo de implementación)
|
||||||
NSString *name;
|
NSString *name;
|
||||||
}
|
}
|
||||||
// Notación conveneinte para acceso público de las variables para generar un método setter
|
// Notación conveneinte para acceso público de las variables para generar un
|
||||||
// Por defecto, el nombre del método setter 'set' seguido del nombre de variable @property
|
// 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 int propInt; // Nombre del método 'setter' = 'setPropInt'
|
||||||
@property (copy) id copyId; // (copy) => Copia el objeto durante la asignación
|
@property (copy) id copyId; // (copy) => Copia el objeto durante la asignación
|
||||||
// (readonly) => No se le puede asignar un valor fuera de @interface
|
// (readonly) => No se le puede asignar un valor fuera de @interface
|
||||||
@property (readonly) NSString *roString; // utiliza @synthesize en @implementation para crear un accesor
|
@property (readonly) NSString *roString; // utiliza @synthesize en
|
||||||
// Puedes personalizar el nombre del getter y del setter en lugar de utilizar el nombre por defecto "set".
|
// @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;
|
@property (getter=lengthGet, setter=lengthSet:) int length;
|
||||||
|
|
||||||
// Métodos
|
// Métodos
|
||||||
@ -334,23 +347,23 @@ int main (int argc, const char * argv[])
|
|||||||
|
|
||||||
// Métodos de constructor con argumentos
|
// Métodos de constructor con argumentos
|
||||||
- (id)initWithDistance:(int)defaultDistance;
|
- (id)initWithDistance:(int)defaultDistance;
|
||||||
// Los nombres de los métodos de Objective-C son muy descriptivos. Siempre nombra los métodos
|
// Los nombres de los métodos de Objective-C son muy descriptivos.
|
||||||
// de acuerdo con sus argumentos
|
// Siempre nombra los métodos de acuerdo con sus argumentos
|
||||||
|
|
||||||
@end // Define el final de la interfaz
|
@end // Define el final de la interfaz
|
||||||
|
|
||||||
|
|
||||||
// Para acceder a las variables públicas desde el archivo de implementación, @property genera
|
// Para acceder a las variables públicas desde el archivo de implementación,
|
||||||
// un método setter automáticamente. El nombre del método es 'set' seguido de un nombre de variable
|
// @property genera un método setter automáticamente. El nombre del método
|
||||||
// @property:
|
// es 'set' seguido de un nombre de variable @property:
|
||||||
MyClass *myClass = [[MyClass alloc] init]; // Crea una instancia del objeto MyClass
|
MyClass *myClass = [[MyClass alloc] init]; // Crea una instancia del objeto MyClass
|
||||||
[myClass setCount:10];
|
[myClass setCount:10];
|
||||||
NSLog(@"%d", [myClass count]); // imprime => 10
|
NSLog(@"%d", [myClass count]); // imprime => 10
|
||||||
// O utilizando los métodos getter y setter personalizados en @interface:
|
// O utilizando los métodos getter y setter personalizados en @interface:
|
||||||
[myClass lengthSet:32];
|
[myClass lengthSet:32];
|
||||||
NSLog(@"%i", [myClass lengthGet]); // imprime => 32
|
NSLog(@"%i", [myClass lengthGet]); // imprime => 32
|
||||||
// Por conveniencia, puedes utilizar la notación de punto para asignar y acceder a las variables
|
// Por conveniencia, puedes utilizar la notación de punto para asignar y
|
||||||
// de una instancia de objeto.
|
// acceder a las variables de una instancia de objeto.
|
||||||
myClass.count = 45;
|
myClass.count = 45;
|
||||||
NSLog(@"%i", myClass.count); // imprime => 45
|
NSLog(@"%i", myClass.count); // imprime => 45
|
||||||
|
|
||||||
@ -363,13 +376,14 @@ MyClass *myClass = [[MyClass alloc] init]; // Crea una instancia de objeto Mycla
|
|||||||
NSString *stringFromInstanceMethod = [myClass instanceMethodWithParameter:@"Hello"];
|
NSString *stringFromInstanceMethod = [myClass instanceMethodWithParameter:@"Hello"];
|
||||||
|
|
||||||
// Selectors
|
// Selectors
|
||||||
// Una forma dinámica de representar métodos. Utilizados para llamar métodos de una clase,
|
// Una forma dinámica de representar métodos. Utilizados para llamar métodos
|
||||||
// pasar métodos a través de funciones para avisar a otras clases para que lo llamen, y
|
// de una clase, pasar métodos a través de funciones para avisar a otras clases
|
||||||
// para guardar métodos como una variable.
|
// 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
|
// SEL es el tipo de dato. @selector() devuelve un selector del nombre de
|
||||||
// methodAparameterAsString:andAParameterAsNumber: es un nombre para un método en MyClass
|
// método proveído methodAparameterAsString:andAParameterAsNumber: es un nombre
|
||||||
|
// para un método en MyClass
|
||||||
SEL selectorVar = @selector(methodAParameterAsString:andAParameterAsNumber:);
|
SEL selectorVar = @selector(methodAParameterAsString:andAParameterAsNumber:);
|
||||||
if ([myClass respondsToSelector:selectorVar]) { // Revisa si la clase contiene un método
|
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
|
// Debe de poner todos los argumentos de método en un solo objeto para mandar una
|
||||||
// función performSelector.
|
// función performSelector.
|
||||||
NSArray *arguments = [NSArray arrayWithObjects:@"Hello", @4, nil];
|
NSArray *arguments = [NSArray arrayWithObjects:@"Hello", @4, nil];
|
||||||
@ -390,8 +404,8 @@ if ([myClass respondsToSelector:selectorVar]) { // Revisa si la clase contiene u
|
|||||||
_count = 5; // Hace referencia a "int count" de la interfaz de MyClass
|
_count = 5; // Hace referencia a "int count" de la interfaz de MyClass
|
||||||
// Accede variables definidas en el archivo de implementación:
|
// Accede variables definidas en el archivo de implementación:
|
||||||
distance = 18; // Hace referencia a "long distance" de la implementación de MyClass
|
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 utilizar una variable @property en el archivo de implementación, utiliza
|
||||||
// para crear una variable de acceso:
|
// @synthesize para crear una variable de acceso:
|
||||||
@synthesize roString = _roString; // _roString ahora está disponible en @implementation
|
@synthesize roString = _roString; // _roString ahora está disponible en @implementation
|
||||||
|
|
||||||
// Lamado antes de llamar algún método o instanciar cualquier objeto
|
// Lamado antes de llamar algún método o instanciar cualquier objeto
|
||||||
@ -406,7 +420,8 @@ distance = 18; // Hace referencia a "long distance" de la implementación de MyC
|
|||||||
// del objeto es cero
|
// del objeto es cero
|
||||||
- (void)dealloc
|
- (void)dealloc
|
||||||
{
|
{
|
||||||
[height release]; // Si no utilizas ARC, asegúrate de liberar las variables de objeto de las clases
|
[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
|
[super dealloc]; // y llama el método dealloc de la clase padre
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -414,7 +429,8 @@ distance = 18; // Hace referencia a "long distance" de la implementación de MyC
|
|||||||
// Este es el constructor por defecto que es llamado cuando el objeto es inicializado.
|
// Este es el constructor por defecto que es llamado cuando el objeto es inicializado.
|
||||||
- (id)init
|
- (id)init
|
||||||
{
|
{
|
||||||
if ((self = [super init])) // 'super' es utilizado para acceder a los métodos de la clase padre.
|
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.
|
self.count = 1; // 'self' es utilizado para que el objeto se llame a sí mismo.
|
||||||
}
|
}
|
||||||
@ -466,18 +482,20 @@ distance = 18; // Hace referencia a "long distance" de la implementación de MyC
|
|||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// Categorías
|
// Categorías
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// Una categoría es un grupo de métodos diseñados para extender una clase. Te permiten agregar
|
// Una categoría es un grupo de métodos diseñados para extender una clase.
|
||||||
// nuevos métodos a una clase existente por propósitos de organización. Éstos no deben de ser
|
// Te permiten agregar nuevos métodos a una clase existente por propósitos
|
||||||
// confundidos con subclases.
|
// de organización. Éstos no deben de serconfundidos con subclases.
|
||||||
// Las subclases existen para CAMBIAR la funcionalidad de un objeto mientras que las categorías
|
// Las subclases existen para CAMBIAR la funcionalidad de un objeto mientras
|
||||||
// le AGREGAN funcionalidad de un objeto.
|
// que las categoríasle AGREGAN funcionalidad de un objeto.
|
||||||
// Las categorías te permiten:
|
// Las categorías te permiten:
|
||||||
// -- Agregar métodos a una clase existente por propósitos de oganización.
|
// -- 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.
|
// -- 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.
|
// -- 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
|
// NOTA: No sobreescribas los métodos de las clases base en una categoría
|
||||||
// de poder hacerlo. Sobreescribir métodos puede causar errores en la compilación después entre
|
// aunque tengas la habilidad de poder hacerlo. Sobreescribir métodos puede
|
||||||
// diferentes categorías y puede arruinar el propósito de las categorías de solo AGREGAR funcionalidad.
|
// 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.
|
// Utiliza subclass para sobreescribir métodos.
|
||||||
|
|
||||||
// Aquí una clase base simple, Car.
|
// Aquí una clase base simple, Car.
|
||||||
@ -508,17 +526,20 @@ distance = 18; // Hace referencia a "long distance" de la implementación de MyC
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
// Ahora, si quisieramos crear un objeto Truck (Camión), crearíamos una subclase de Car (Carro) como
|
// Ahora, si quisieramos crear un objeto Truck (Camión), crearíamos una
|
||||||
// si le cambiaramos de funcionalidad de Car para que se comporte como un camión. Pero digamos que
|
// subclase de Car (Carro) como si le cambiaramos de funcionalidad de Car
|
||||||
// únicamente queremos agregar funcionalidad al Car (Carro) existente. Un buen ejemplo sería limpiar
|
// para que se comporte como un camión. Pero digamos que únicamente queremos
|
||||||
// el carro. Así que crearíamos una cateog®iea para agregar los métodos de limpieza:
|
// 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)
|
// Archivo @interface: Car+Clean.h (NombreBaseDeClase+NombreDeCategoria.h)
|
||||||
#import "Car.h" // Asegúrate de improtar la clase que deseas extener.
|
#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
|
@interface Car (Clean) // El nombre de la categoría está dentro de (),
|
||||||
// clase base
|
// seguido del nombre de la clase base
|
||||||
|
|
||||||
- (void)washWindows; // Nombres de los nuevos métodos que le agregamos a nuestro objeto Car
|
- (void)washWindows; // Nombres de los nuevos métodos que le agregamos
|
||||||
|
// a nuestro objeto Car
|
||||||
- (void)wax;
|
- (void)wax;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@ -537,10 +558,12 @@ distance = 18; // Hace referencia a "long distance" de la implementación de MyC
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
// Cualquier instancia del objeto Car tiene la habilidad de utilizar una categoría. Todo lo
|
// Cualquier instancia del objeto Car tiene la habilidad de utilizar una
|
||||||
// que necesitan es importarlo:
|
// categoría. Todo lo que necesitan es importarlo:
|
||||||
#import "Car+Clean.h" // Importa todas las diferentes categorías que necesites utilizar
|
#import "Car+Clean.h" // Importa todas las diferentes categorías que
|
||||||
#import "Car.h" // También debes de importar la clase base para su funcionalidad original
|
// necesites utilizar
|
||||||
|
#import "Car.h" // También debes de importar la clase base para su
|
||||||
|
// funcionalidad original
|
||||||
|
|
||||||
int main (int argc, const char * argv[]) {
|
int main (int argc, const char * argv[]) {
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
@ -554,23 +577,27 @@ int main (int argc, const char * argv[]) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Objective-C no tiene declaraciones para métodos protegidos, pero los puedes simular.
|
// Objective-C no tiene declaraciones para métodos protegidos, pero los puedes
|
||||||
// Crea una categoría conteniendo todos los métodos protegidos, luego importa ÚNICAMENTE
|
// simular. Crea una categoría conteniendo todos los métodos protegidos,
|
||||||
// al archivo @implementation de una clase que pertenece a la clase Car.
|
// luego importa ÚNICAMENTE al archivo @implementation de una clase que
|
||||||
@interface Car (Protected) // Nombrando la categoría 'Protected' para recordar que los métodos
|
// pertenece a la clase Car.
|
||||||
// están protegidos
|
@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
|
- (void)lockCar; // Los métodos enlistados aquí solo puedens ser creados
|
||||||
|
// por objetos Car
|
||||||
|
|
||||||
@end
|
@end
|
||||||
// Para utilizar los métodos protegidos, importa la categoría, luego implementa sus métodos:
|
// Para utilizar los métodos protegidos, importa la categoría,
|
||||||
#import "Car+Protected.h" // Recuerda, importa únicamente el archivo de @implementation
|
// luego implementa sus métodos:
|
||||||
|
#import "Car+Protected.h" // Recuerda, importa únicamente el archivo
|
||||||
|
// de @implementation
|
||||||
|
|
||||||
@implementation Car
|
@implementation Car
|
||||||
|
|
||||||
- (void)lockCar {
|
- (void)lockCar {
|
||||||
NSLog(@"Car locked."); // Las instancias de Car no puede utilizar lockCar porque no se
|
NSLog(@"Car locked."); // Las instancias de Car no puede utilizar
|
||||||
// encuentra en @interface
|
// lockCar porque no se encuentra en @interface
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@ -578,8 +605,8 @@ int main (int argc, const char * argv[]) {
|
|||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// Extensiones
|
// Extensiones
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// Las Extensions te permiten sobreescribir atributos de propiedades de acceso público y métodos de
|
// Las Extensions te permiten sobreescribir atributos de propiedades de
|
||||||
// un @interface
|
// acceso público y métodos de un @interface
|
||||||
// Archivo @interface: Shape.h
|
// Archivo @interface: Shape.h
|
||||||
@interface Shape : NSObject
|
@interface Shape : NSObject
|
||||||
|
|
||||||
@ -588,17 +615,21 @@ int main (int argc, const char * argv[]) {
|
|||||||
- (int)getNumOfSides;
|
- (int)getNumOfSides;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
// Puedes sobreescribir la variable numOfSides o el métodos getNumOfSlides para modificarlos con una
|
// Puedes sobreescribir la variable numOfSides o el métodos getNumOfSlides
|
||||||
// extensión:
|
// para modificarlos con una extensión:
|
||||||
// Archivo @implementation: Shape.m
|
// Archivo @implementation: Shape.m
|
||||||
#import "Shape.h"
|
#import "Shape.h"
|
||||||
// Las extensiones se encuentran en el mismo archivo que el archivo de @implementation
|
// Las extensiones se encuentran en el mismo archivo que el archivo
|
||||||
@interface Shape () // () después del nombre de la clase base declara una extensión
|
// 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.
|
@property (copy) NSNumber *numOfSides; // Hacer numOfSlides copy en lugar
|
||||||
-(NSNumber)getNumOfSides; // Hacer que getNumOfSides devuelva un NSNumber en lugar de un int.
|
// de readonly.
|
||||||
-(void)privateMethod; // También puedes crear una nuevos métodos privados dentro de las
|
-(NSNumber)getNumOfSides; // Hacer que getNumOfSides devuelva un NSNumber
|
||||||
// extensiones
|
// en lugar de un int.
|
||||||
|
-(void)privateMethod; // También puedes crear una nuevos métodos privados
|
||||||
|
// dentro de las extensiones
|
||||||
|
|
||||||
@end
|
@end
|
||||||
// @implementation principal:
|
// @implementation principal:
|
||||||
@ -606,8 +637,8 @@ int main (int argc, const char * argv[]) {
|
|||||||
|
|
||||||
@synthesize numOfSides = _numOfSides;
|
@synthesize numOfSides = _numOfSides;
|
||||||
|
|
||||||
-(NSNumber)getNumOfSides { // Todas las declaraciones dentro de extensions deben de ser
|
-(NSNumber)getNumOfSides { // Todas las declaraciones dentro de extensions
|
||||||
// dentro de @implementation
|
// deben de ser dentro de @implementation
|
||||||
return _numOfSides;
|
return _numOfSides;
|
||||||
}
|
}
|
||||||
-(void)privateMethod {
|
-(void)privateMethod {
|
||||||
@ -619,36 +650,44 @@ int main (int argc, const char * argv[]) {
|
|||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// Protocolos
|
// Protocolos
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// Un protocolo declara métodos que pueden ser implementados por cualquier otra clase
|
// Un protocolo declara métodos que pueden ser implementados por cualquier otra
|
||||||
// Los protocolos no son clases. Simplementen define una interfaz que otros objetos
|
// clase. Los protocolos no son clases. Simplementen define una interfaz que
|
||||||
// deben de implementar.
|
// otros objetos deben de implementar.
|
||||||
// Archivo @protocol: "CarUtilities.h"
|
// Archivo @protocol: "CarUtilities.h"
|
||||||
@protocol CarUtilities <NSObject> // <NSObject> => Nombre de otro protocolo que se incluye en éste
|
@protocol CarUtilities <NSObject> // <NSObject> => Nombre de otro protocolo
|
||||||
@property BOOL engineOn; // La clase que lo adopta debe de utilizar @synthesize para todas las
|
// que se incluye en éste
|
||||||
// @properties definidas
|
@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
|
- (void)turnOnEngine; // y todos los métodos definidos
|
||||||
@end
|
@end
|
||||||
// A continuación una clase ejemplo que implementa el protcolo
|
// A continuación una clase ejemplo que implementa el protcolo
|
||||||
#import "CarUtilities.h" // Importar el archivo @protocol.
|
#import "CarUtilities.h" // Importar el archivo @protocol.
|
||||||
|
|
||||||
@interface Car : NSObject <CarUtilities> // El nombre del protocolo dentro de <>
|
@interface Car : NSObject <CarUtilities> // El nombre del protocolo dentro de <>
|
||||||
// No necesitas los nombres de @property o métodos aquí para CarUtilities. Estos solo
|
// No necesitas los nombres de @property o métodos aquí para CarUtilities.
|
||||||
// es requerido por @implementation.
|
// Estos solo es requerido por @implementation.
|
||||||
- (void)turnOnEngineWithUtilities:(id <CarUtilities>)car; // También Puedes utilizar protocolos como datos.
|
- (void)turnOnEngineWithUtilities:(id <CarUtilities>)car; // También Puedes
|
||||||
|
// utilizar protocolos
|
||||||
|
// como datos.
|
||||||
@end
|
@end
|
||||||
// El @implementation necesita que se implementen @properties y métodos del protocolo.
|
// El @implementation necesita que se implementen @properties y métodos
|
||||||
|
// del protocolo.
|
||||||
@implementation Car : NSObject <CarUtilities>
|
@implementation Car : NSObject <CarUtilities>
|
||||||
|
|
||||||
@synthesize engineOn = _engineOn; // Crear una declaración @synthesize para el @property engineOn.
|
@synthesize engineOn = _engineOn; // Crear una declaración @synthesize para el
|
||||||
|
// @property engineOn.
|
||||||
|
|
||||||
- (void)turnOnEngine { // Implementa turnOnEngine como quieras. Los protocolos no definen
|
- (void)turnOnEngine { // Implementa turnOnEngine como quieras. Los
|
||||||
|
// protocolos no definen
|
||||||
_engineOn = YES; // cómo implementas un método, con tal de que lo implementes.
|
_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.
|
// Puedes utilizar un protocolo como data mientras sepas quee métodos y variables
|
||||||
|
// tiene implementado.
|
||||||
- (void)turnOnEngineWithCarUtilities:(id <CarUtilities>)objectOfSomeKind {
|
- (void)turnOnEngineWithCarUtilities:(id <CarUtilities>)objectOfSomeKind {
|
||||||
[objectOfSomeKind engineOn]; // Tienes acceso a las variables
|
[objectOfSomeKind engineOn]; // Tienes acceso a las variables
|
||||||
[objectOfSomeKind turnOnEngine]; // y los métodos del objeto
|
[objectOfSomeKind turnOnEngine]; // y los métodos del objeto
|
||||||
[objectOfSomeKind engineOn]; // Puede o no puede ser YES. La clase lo implementa como se quiera.
|
[objectOfSomeKind engineOn]; // Puede o no puede ser YES. La clase lo
|
||||||
|
// implementa como se quiera.
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@ -659,18 +698,23 @@ Car *carInstance = [[Car alloc] init];
|
|||||||
if ([carInstance engineOn]) {
|
if ([carInstance engineOn]) {
|
||||||
NSLog(@"Car engine is on."); // imprime => "Car engine is on."
|
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:
|
// 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)]) {
|
if ([myClass conformsToProtocol:@protocol(CarUtilities)]) {
|
||||||
NSLog(@"This does not run as the MyClass class does not implement the CarUtilities protocol.");
|
NSLog(@"This does not run as the MyClass class does not implement the CarUtilities protocol.");
|
||||||
} else if ([carInstance conformsToProtocol:@protocol(CarUtilities)]) {
|
} else if ([carInstance conformsToProtocol:@protocol(CarUtilities)]) {
|
||||||
NSLog(@"This does run as the Car class implements the CarUtilities protocol.");
|
NSLog(@"This does run as the Car class implements the CarUtilities protocol.");
|
||||||
}
|
}
|
||||||
// Las categorías también pueden implementar protcolos: @interface Car (CarCategory) <CarUtilities>
|
// Las categorías también pueden implementar protcolos: @interface Car
|
||||||
// Puedes implementar varios protocolos: @interface Car : NSObject <CarUtilities, CarCleaning>
|
// (CarCategory) <CarUtilities>
|
||||||
// NOTA: Si dos o más protocolos dependen entre sí, asegúrate de declararlos de manera adelantada:
|
// 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"
|
#import "Brother.h"
|
||||||
|
|
||||||
@protocol Brother; // Declaración adelantada. Sin ésto, el compilador tira un error.
|
@protocol Brother; // Declaración adelantada. Sin ésto, el compilador
|
||||||
|
// tira un error.
|
||||||
|
|
||||||
@protocol Sister <NSObject>
|
@protocol Sister <NSObject>
|
||||||
|
|
||||||
@ -678,10 +722,11 @@ if ([myClass conformsToProtocol:@protocol(CarUtilities)]) {
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
// Ver si el problema es que Sister depende de Brother, y Broteher dependa de Sister.
|
// Ver si el problema es que Sister depende de Brother,
|
||||||
|
// y Brother dependa de Sister.
|
||||||
#import "Sister.h"
|
#import "Sister.h"
|
||||||
|
|
||||||
@protocol Sister; // Estas líenas detienen la recursión, solucionando el problema.
|
@protocol Sister; // Estas líneas detienen la recursión, resolviendo el problema.
|
||||||
|
|
||||||
@protocol Brother <NSObject>
|
@protocol Brother <NSObject>
|
||||||
|
|
||||||
@ -693,23 +738,30 @@ if ([myClass conformsToProtocol:@protocol(CarUtilities)]) {
|
|||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// Bloques
|
// Bloques
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// Los bloques son declaraciones de código, tal como una función, pueden ser utilizados como data
|
// Los bloques son declaraciones de código, tal como una función, pueden
|
||||||
// A continuación un bloque simple con un argumento entero que devuelve un el argumento más 4.
|
// 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.
|
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.
|
void (^noParameterBlockVar)(void); // Ejemplo de una declaración de variable
|
||||||
// Los bloques tienen acceso a variables del mismo ámbito. Pero las variables son solo readonly
|
// de bloque sin argumentos.
|
||||||
// y el valor pasado al bloque es el valor de la variable cuando el bloque es creado.
|
// Los bloques tienen acceso a variables del mismo ámbito. Pero las variables
|
||||||
int outsideVar = 17; // Si modificamos outsideVar después de declarar addUp, outsideVar AÚN es 17.
|
// son solo readonly y el valor pasado al bloque es el valor de la variable
|
||||||
__block long mutableVar = 3; // __block hace que las variables se puedan escribir en bloques.
|
// cuando el bloque es creado.
|
||||||
addUp = ^(int n) { // Remueve (int n) para tener un bloque que no recibe ningún parámetro
|
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.");
|
NSLog(@"You may have as many lines in a block as you would like.");
|
||||||
NSSet *blockSet; // También puedes declarar variables locales.
|
NSSet *blockSet; // También puedes declarar variables locales.
|
||||||
mutableVar = 32; // Asignar un nuevo valor a la variable __block.
|
mutableVar = 32; // Asignar un nuevo valor a la variable __block.
|
||||||
return n + outsideVar; // Declaraciones de retorno son opcionales.
|
return n + outsideVar; // Declaraciones de retorno son opcionales.
|
||||||
}
|
}
|
||||||
int addUp = add(10 + 16); // Llama al bloque de código con argumentos.
|
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
|
// Los bloques son usualmente utilizados como argumentos a funciones que
|
||||||
// más adelante o para callbacks.
|
// son llamados más adelante o para callbacks.
|
||||||
@implementation BlockExample : NSObject
|
@implementation BlockExample : NSObject
|
||||||
|
|
||||||
- (void)runBlock:(void (^)(NSString))block {
|
- (void)runBlock:(void (^)(NSString))block {
|
||||||
@ -724,51 +776,72 @@ int addUp = add(10 + 16); // Llama al bloque de código con argumentos.
|
|||||||
// Manejo de memoria
|
// Manejo de memoria
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
/*
|
/*
|
||||||
Para cada objeto utilizado en una aplicación, la memoria debe de ser alocada para ese objeto. Cuando
|
Para cada objeto utilizado en una aplicación, la memoria debe de ser alocada
|
||||||
la aplicación termina de utilizar ese objeto, la memoria debe de ser desalocada para asegurar la
|
para ese objeto. Cuando la aplicación termina de utilizar ese objeto, la
|
||||||
eficiencia de la aplicación.
|
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
|
Objetive-C no utiliza garbage collection, y en lugar de eso utiliza conteos
|
||||||
haya al menos una referencia del objeto (también conocido como tener un objeto de adueñado), entonces
|
de referencias. Mientras haya al menos una referencia del objeto (también
|
||||||
el objeto estará disponible para su uso.
|
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
|
Cuando una instancia es dueña un objeto, su contador de referencia incrementa
|
||||||
el objeto es liberado, el contador de referencia decrementa uno. Cuando el conteo de referencia
|
por uno. Cuando el objeto es liberado, el contador de referencia decrementa uno.
|
||||||
es cero, el objeto es removido de la memoria.
|
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:
|
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.
|
(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
|
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
|
[classVar release]; // Decrementa el conteo de referencias de classVar's
|
||||||
// 'retain'
|
// 'retain'
|
||||||
// 'retain' adueña la instancia de objeto existente e incrementa el conteo de referencia por uno. Devuelve un puntero al objeto.
|
// 'retain' adueña la instancia de objeto existente e incrementa el conteo de
|
||||||
MyClass *newVar = [classVar retain]; // Si classVar es liberado, el objeto aún se queda en memoria porque newVar es el dueño.
|
// referencia por uno. Devuelve un puntero al objeto.
|
||||||
[classVar autorelease]; // Remueve el adueñamiento de un objeto al final del bloque @autoreleasepool. 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 puede utilizar 'retain' y 'assign' también para pequeñas
|
||||||
@property (retain) MyClass *instance; // Libera el valor viejo y retiene uno nuevo (referencia fuerte)
|
// definiciones convenientes
|
||||||
@property (assign) NSSet *set; // Apunta a un nuevo valor sin retener/liberar una referencia vieja (débil)
|
@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)
|
// 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
|
// Debido a que el manejo de memoria puede ser un dolor, en Xcode 4.2 y iOS 4
|
||||||
// de Referencias (ARC).
|
// 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
|
// 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.
|
// utilizar ARC, no se debe de utilizar retain, release o autorelease.
|
||||||
MyClass *arcMyClass = [[MyClass alloc] init];
|
MyClass *arcMyClass = [[MyClass alloc] init];
|
||||||
// ... código utilizando arcMyClass
|
// ... código utilizando arcMyClass
|
||||||
// Sin ARC, necesitarás llamar: [arcMyClass release] luego de terminar de utilizar arcMyClass. Pero con ARC,
|
// Sin ARC, necesitarás llamar: [arcMyClass release] luego de terminar de
|
||||||
// no hay necesidad. Insertará automáticamente la declaración de liberación.
|
// 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'
|
// Mientras que para los atributos de @property 'assign' y 'retain', con ARC
|
||||||
@property (weak) MyClass *weakVar; // 'weak' no adueña el objeto. El conteo de referencias de la instancia original
|
// utilizarás 'weak' y 'strong'
|
||||||
// es fijado a ceor, weakVar autom´åticamente recibe el valor de nil para evitar cualquier 'crashing'.
|
@property (weak) MyClass *weakVar; // 'weak' no adueña el objeto. El conteo de
|
||||||
@property (strong) MyClass *strongVar; // 'strong' se adueña del objeto. Asegura que el objeto se quede en memoria.
|
// 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:
|
// 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.
|
__strong NSString *strongString; // Por defecto. La variables de retenida en
|
||||||
__weak NSSet *weakSet; // Referencia débil a un objeto existente. Cuando el objeto existente es liberado, weakSet le es asginado un valor nil
|
// memoria hasta que se salga del ámbito.
|
||||||
__unsafe_unretained NSArray *unsafeArray; // Como __weak, pero unsafeArray no es asginado a nil cuando el objeto existente es liberado.
|
__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
|
## Lecturas sugeridas
|
||||||
|
Loading…
Reference in New Issue
Block a user