ios - objetivo c conversión implícita pierde precisión entera ''NSUInteger''
objective-c compiler-errors (2)
Puede suprimir de forma segura la advertencia con un yeso.
NSUInteger index = arc4random_uniform((uint32_t) predictionArray.count);
No siempre es seguro suprimir las advertencias, así que no vaya a lanzar cosas para deshacerse de las advertencias hasta que descubra si la operación es segura.
Lo que sucede aquí es que NSUInteger
es, en su plataforma, un typedef para un tipo de entero de 64 bits. No siempre es de 64 bits, solo en algunas plataformas. El compilador le advierte que algunos de esos bits se desechan. Si sabe que estos bits no son importantes, solo puede usar un lanzamiento.
En este caso, el resultado es que el index
siempre estará por debajo de 2 32 -1. Si es incluso remotamente posible que predictionArray
contenga 2 32 o más elementos, entonces su programa tiene un error y tendrá que construir una versión de arc4random_uniform()
64 bits. Puedes asegurarlo con el siguiente código:
assert(predictionArray.count <= (uint32_t) -1);
Siguiendo un tutorial en la casa del árbol, veo este popular mensaje de advertencia de Object-C en XCode.
Función de mi botón
- (IBAction)buttonPressed:(UIButton *)sender {
NSUInteger index = arc4random_uniform(predictionArray.count);
self.predictionLabel.text = [predictionArray objectAtIndex:index];
}
Lo veo en la línea NSUInteger, tengo algunos de los flujos de pila similares y parece que hablan de números de 32 bits frente a números de 64 bits y de conversión de tipos, pero no estoy seguro de cómo hacerlo aquí.
Mi predicción
- (void)viewDidLoad
{
[super viewDidLoad];
predictionArray = [[NSArray alloc] initWithObjects:
@"It is certain", @"It is decidely so", @"All signs say YES", @"The stars are not aligned",
@"My reply is no",
@"It is doubtful",
@"Better not tell you now",
@"Concentrate and ask again",
@"Unable to answer now", nil];
// Do any additional setup after loading the view, typically from a nib.
}
Según mi comentario, arc4random_uniform()
toma, y devuelve, un u_int32_t
, un entero sin signo que siempre tiene 32 bits, independientemente de la arquitectura de destino. Sin embargo, predictionArray.count
devuelve un NSUInteger
, que es typedef
d diferente para sistemas de 32 bits y 64 bits; es de 32 bits ( unsigned int
) en un sistema de 32 bits, y de 64 bits ( unsigned long
) en un sistema de 64 bits. Si está ejecutando un sistema de 64 bits, pasar un NSUInteger
64 bits a una función que espera un entero de 32 bits hará que el compilador se queje de que está desechando bits.