Objective-C Language
Tipos de datos básicos
Buscar..
Sintaxis
- BOOL tenerPlutonio = SÍ; // Asignación directa
- BOOL fastEnough = (car.speedInMPH> = 88); // Expresión de comparación
- BOOL fluxCapacitorActive = (havePlutonium && fastEnough); // expresión booleana
- id somethingWicked = [witchesCupboard lastObject]; // Recuperar objeto sin tipo
- id powder = prepareWickedIngredient (somethingWicked); // Pasar y volver
- if ([ingrediente isKindOfClass: [clase Toad]]) {// tipo de tiempo de ejecución de prueba
BOOL
El tipo BOOL
se utiliza para valores booleanos en Objective-C. Tiene dos valores, YES
y NO
, en contraste con los más comunes "verdadero" y "falso".
Su comportamiento es directo e idéntico al del lenguaje C.
BOOL areEqual = (1 == 1); // areEqual is YES
BOOL areNotEqual = !areEqual // areNotEqual is NO
NSCAssert(areEqual, "Mathematics is a lie"); // Assertion passes
BOOL shouldFlatterReader = YES;
if (shouldFlatterReader) {
NSLog(@"Only the very smartest programmers read this kind of material.");
}
Un BOOL
es un elemento primitivo, por lo que no se puede almacenar directamente en una colección de Foundation. Debe estar envuelto en un NSNumber
. Clang proporciona una sintaxis especial para esto:
NSNumber * yes = @YES; // Equivalent to [NSNumber numberWithBool:YES]
NSNumber * no = @NO; // Equivalent to [NSNumber numberWithBool:NO]
La implementación de BOOL
se basa directamente en C's, ya que es un typedef del bool
tipo estándar C99. Los valores de YES
y NO
están definidos para __objc_yes
y __objc_no
, respectivamente. Estos valores especiales son los compiladores incorporados introducidos por Clang, que se traducen a (BOOL)1
y (BOOL)0
. Si no están disponibles, YES
y NO
se definen directamente como la forma de entero de conversión. Las definiciones se encuentran en el encabezado de tiempo de ejecución de Objective-C objc.h
carné de identidad
id
es el puntero de objeto genérico, un tipo Objective-C que representa "cualquier objeto". Una instancia de cualquier clase de Objective-C se puede almacenar en una variable de id
. Un id
y cualquier otro tipo de clase pueden asignarse de ida y vuelta sin lanzar:
id anonymousSurname = @"Doe";
NSString * surname = anonymousSurname;
id anonymousFullName = [NSString stringWithFormat:@"%@, John", surname];
Esto se vuelve relevante cuando se recuperan objetos de una colección. Los tipos de métodos de objectAtIndex:
como objectAtIndex:
son id
por exactamente este motivo.
DataRecord * record = [records objectAtIndex:anIndex];
También significa que un parámetro de función o método escrito como id
puede aceptar cualquier objeto.
Cuando un objeto se escribe como id
, se le puede pasar cualquier mensaje conocido: el envío del método no depende del tipo de tiempo de compilación.
NSString * extinctBirdMaybe =
[anonymousSurname stringByAppendingString:anonymousSurname];
Un mensaje al que el objeto no responde realmente causará una excepción en el tiempo de ejecución, por supuesto.
NSDate * nope = [anonymousSurname addTimeInterval:10];
// Raises "Does not respond to selector" exception
Protección contra excepción.
NSDate * nope;
if([anonymousSurname isKindOfClass:[NSDate class]]){
nope = [anonymousSurname addTimeInterval:10];
}
El tipo de id
está definido en objc.h
typedef struct objc_object {
Class isa;
} *id;
SEL
Los selectores se utilizan como identificadores de método en Objective-C.
En el siguiente ejemplo, hay dos selectores. new
y setName:
Person* customer = [Person new];
[customer setName:@"John Doe"];
Cada par de corchetes corresponde a un mensaje enviado. En la primera línea enviamos un mensaje que contiene el new
selector a la clase Person
y en la segunda línea enviamos un mensaje que contiene el setName:
selector y una cadena. El receptor de estos mensajes utiliza el selector para buscar la acción correcta para realizar.
La mayoría de las veces, el paso de mensajes con la sintaxis de corchete es suficiente, pero ocasionalmente necesita trabajar con el propio selector. En estos casos, el tipo SEL
se puede utilizar para mantener una referencia al selector.
Si el selector está disponible en tiempo de compilación, puede usar @selector()
para obtener una referencia a él.
SEL s = @selector(setName:);
Y si necesita encontrar el selector en tiempo de ejecución, use NSSelectorFromString.
SEL s NSSelectorFromString(@"setName:");
Cuando use NSSelectorFromString, asegúrese de envolver el nombre del selector en una NSString.
Se usa comúnmente para verificar si un delegado implementa un método opcional.
if ([self.myDelegate respondsToSelector:@selector(doSomething)]) {
[self.myDelegate doSomething];
}
IMP (puntero de implementación)
IMP es un tipo C que se refiere a la implementación de un método, también conocido como puntero de implementación. Es un puntero al inicio de la implementación de un método.
Sintaxis:
id (*IMP)(id, SEL, …)
IMP se define por:
typedef id (*IMP)(id self,SEL _cmd,…);
Para acceder a este IMP, se puede usar el mensaje "methodForSelector" .
Ejemplo 1:
IMP ImpDoSomething = [myObject methodForSelector:@selector(doSomething)];
El método dirigido por el IMP se puede llamar mediante la eliminación de la referencia del IMP.
ImpDoSomething(myObject, @selector(doSomething));
Así que estas llamadas son iguales:
myImpDoSomething(myObject, @selector(doSomething));
[myObject doSomething]
[myObject performSelector:mySelector]
[myObject performSelector:@selector(doSomething)]
[myObject performSelector:NSSelectorFromString(@"doSomething")];
Ejemplo: 2:
SEL otherWaySelector = NSSelectorFromString(@“methodWithFirst:andSecond:andThird:");
IMP methodImplementation = [self methodForSelector:otherWaySelector];
result = methodImplementation( self,
betterWaySelector,
first,
second,
third );
NSLog(@"methodForSelector : %@", result);
Aquí, llamamos a [NSObject methodForSelector, que nos devuelve un puntero a la función C que implementa el método, al que podemos llamar directamente.
NSInteger y NSUInteger
El NSInteger es solo un typedef para un int o un largo dependiendo de la arquitectura. Lo mismo ocurre con un NSUInteger que es un typedef para las variantes sin firmar. Si marca el NSInteger verá lo siguiente:
#if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64
typedef long NSInteger;
typedef unsigned long NSUInteger;
#else
typedef int NSInteger;
typedef unsigned int NSUInteger;
#endif
La diferencia entre un int firmado o no firmado o largo es que un int firmado o largo puede contener valores negativos. El rango del int es -2 147 483 648 a 2 147 483 647, mientras que el int sin firma tiene un rango de 0 a 4 294 967 295. El valor se duplica porque el primer bit ya no se usa para decir que el valor es negativo o no. Para un largo y NSInteger en arquitecturas de 64 bits, el rango es mucho más amplio.
La mayoría de los métodos que proporciona Apple están devolviendo un entero NS (U) sobre el int normal. Recibirá una advertencia si intenta convertirlo en un int normal porque perderá precisión si está ejecutando en una arquitectura de 64 bits. No es que importe en la mayoría de los casos, pero es más fácil usar NS (U) Integer. Por ejemplo, el método de conteo en una matriz devolverá un NSUInteger.
NSNumber *iAmNumber = @0;
NSInteger iAmSigned = [iAmNumber integerValue];
NSUInteger iAmUnsigned = [iAmNumber unsignedIntegerValue];
NSLog(@"%ld", iAmSigned); // The way to print a NSInteger.
NSLog(@"%lu", iAmUnsigned); // The way to print a NSUInteger.
Al igual que un BOOL, el Entero NS (U) es un tipo de datos primitivo, por lo que a veces necesita envolverlo en un NSNumber, puede usar @ antes del entero para convertirlo como arriba y recuperarlo usando los métodos a continuación. Pero para convertirlo en NSNumber, también puedes usar los siguientes métodos:
[NSNumber numberWithInteger:0];
[NSNumber numberWithUnsignedInteger:0];