2012-01-11 9 views
11

Estoy haciendo un tutorial de carrito de la compra: Tengo una matriz que recopila entradas de un campo de texto y luego las muestra en NSTableView. Puede verificar un elemento y eliminarlo de la lista. Quiero mostrar una advertencia solo si hay algo marcado. Por lo tanto, tengo esto:Advertencia "La conversión implícita pierde precisión de enteros ..."

-(IBAction)removeItemFromShoppingList:(id)sender { 
     int selectedItemIndex = [shoppingListTableView selectedRow]; 
     if (selectedItemIndex == -1) return; 
     NSAlert *alert = [[NSAlert alloc] init]; 
     ... 
     [alert runModal]; 
     [alert release]; 
} 

En la línea 2 aquí (int selectedItemIndex...) recibo una advertencia de color amarillo: conversión implícita pierde precisión entero:’NSInteger’ (también conocido como ‘largo’) a ‘int’.

¿Por qué?

+2

Tal vez porque un int es más corto que un tiempo? –

+0

Como comentario adicional, solo debería ver esta advertencia al construir para el simulador, ya que NSInteger tiene 32 bits cuando se construye para el dispositivo. Como han dicho otros, debe usar los mismos tipos de precisión o emitir explícitamente para decir "Sé con certeza que nunca será mayor que 32 bytes". –

+0

¿Qué quiere decir "solo construir para el simulador"? (Es para una aplicación Mac, no para iOS) – janeh

Respuesta

14

De la documentación de Apple:

Cuando la construcción de aplicaciones de 32 bits, NSInteger es un número entero de 32 bits. Una aplicación de 64 bits trata a NSInteger como un entero de 64 bits.

#if __LP64__ || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64 
typedef long NSInteger; 
#else 
typedef int NSInteger; 
#endif 

ACTUALIZACIÓN:

explicar en detalle:

[shoppingListTableView selectedRow] devuelve un NSInteger, y que están construyendo una aplicación de 64 bits, por lo que es en realidad un long.

Puede usar long selectedItemIndex en lugar de int selectedItemIndex para suprimir esta advertencia, pero la advertencia aparece nuevamente al compilar la versión de 32 bits.

Una mejor manera es usar NSInteger selectedItemIndex, que maneja esta caja correctamente.

+1

Recibí el error "redefinición Typedef con diferentes tipos de longitud frente a int" – justicepenny

+0

Recibí el mismo error también –

+2

@KunalBalani y justicepenny no eres Se supone que debe intentar agregar este código a su proyecto. Esto solo muestra cómo NSInteger se define internamente. –

8

Porque su variable es de tipo int y está intentando copiar el valor de una variable de tipo NSInteger en ella. Un NSInteger puede contener valores mayores que un int puede, por lo que recibe una advertencia de que es posible el desbordamiento. Probablemente la solución más simple es cambiar int a NSInteger. (Cuando desee copiar el valor de una variable para ejecutar pruebas en ella, generalmente debería usar una variable del mismo tipo).

+0

Ok, estoy sorprendido de obtener esto, ¡ya que copié el tutorial del libro! Fue escrito para XC3, ¿entonces tal vez ese es el problema? (¿O un error tipográfico en el libro?) – janeh

+8

¡Si las personas que escribieron libros fueran grandes programadores, enviarían productos en lugar de libros! :) – Fletch

+0

@Fletch, noté que el código de muestra que no muestra la advertencia es para SDK 10.6, mi proyecto es para 10.7 - ¡muestra la advertencia! – janeh

1

Uso

NSInteger selectedItemIndex = [shoppingListTableView selectedRow]; 

En lugar de

int selectedItemIndex = [shoppingListTableView selectedRow]; 
0

salga advertencia acaba de hacer:

int selectedItemIndex = (int)[shoppingListTableView selectedRow];    
6

Uso

int selectedItemIndex = (int)[shoppingListTableView selectedRow]; 

lugar de

int selectedItemIndex = [shoppingListTableView selectedRow]; 
1

Puede actualizar la configuración del proyecto, para eliminar todos los

Implicit conversion loses integer precision advertencias, mediante el establecimiento de

Implicit Conversion to 32 Bit Type a No

en configuración de generación del proyecto.

enter image description here

Cuestiones relacionadas