2010-03-10 8 views
38

Estoy tratando de probar si una propiedad se ha establecido aún. Sé que con los objetos que tenemos:Valor predeterminado de una estructura Objective-C y cómo probar

CGRect ppGoalFrame; 
LocalPlaySetup *localPlaySetup; 

y puedo probar

if (localPlaySetup == nil) 

pero si intento para probar la CGRect con nula o == == NULL

if (ppGoalFrame == nil) 

consigo

invalid operands to binary == (have 'CGRect' and 'void *') 

Así es el CGRect "vacío", nulo, nulo ...? antes de que se establezca? Obviamente no puedo comparar CGrect con un puntero de vacío (no puedo usar ppGoalFrame == void); ¿Hay alguna otra forma de probar esto? El Objective-C hasta ahora es bastante fácil de entender, pero tan pronto como se ve el C, me pierdo un poco.

Respuesta

89

Solo los punteros pueden ser nulos. CGRect es una estructura: representa un bloque contiguo de memoria. La única forma de saber si se ha configurado para verificar su contenido.

Apple proporciona una constante CGRectNull. Puede establecer su variable para esto y usar la función CGRectIsNull para determinar si se ha configurado. CGRectNull no es lo mismo que CGRectZero, por lo que no debe preocuparse si el valor deseado es cero.

Tenga en cuenta que CGRectNull simplemente contiene una estructura CGRect llena de valores que Apple puede identificar más adelante para la función CGRectIsNull. No es lo mismo nulo que al comparar punteros.

+22

Terminó usando CGRectIsEmpty para probar. No tiene que configurarlos de ninguna manera. Tu respuesta me puso en el camino correcto, así que gracias. – typeoneerror

0

No creo que pueda hacer una comparación binaria de una estructura C, que es what CGRect is. Una búsqueda rápida en Google y la comprobación de la referencia de escritorio de C for Dummies no dieron resultado. Puede declarar CGRect ppGoalFrame, inicializar los miembros de la estructura con los valores predeterminados (si aún no lo están) y probar los miembros de la estructura.

Actualización Editar: Esta question has been asked para C estructuras.

+0

La historia es diferente para Objective-C cuando se discuten variables de instancia. – gavinb

+0

@gavinb: Tal vez. Todavía estoy retocando mi C antes de sumergirme en Objective-C. –

44

Todas las variables de instancia en una clase Objective-C se inicializan a cero. Entonces todos los apuntadores son nil, los números son 0 y las estructuras se ponen a cero. Como CGRect es una estructura simple, se inicializará en origin.x=0, origin.y=0, size.width=0, size.height=0.

Para comprobar si su CGRect se ha configurado, debe compararlo (por valor) a cero. La función CGRectIsEmpty va a hacer exactamente esto:

if (CGRectIsEmpty(ppGoalFrame)) 
{ 
    // ... 
} 
+0

+1 gran respuesta. Puede editarlo para usar la IMO 'CGRectIsEmpty'. –

+0

@Yar Gracias, actualizado como se sugiere. – gavinb

+0

Gracias @gavinb, eso es genial. Personalmente eliminaría la referencia 'CGRectEqualToRect', ya que ahora es" código heredado ". –

2

No hay valor universal "nada". Hay nil para los objetos y NULL para los punteros, pero no hay un equivalente para los tipos de valores simples: siempre tienen algún valor de, incluso si no tiene sentido. Puede tomar un valor arbitrario y decir "Voy a llamar a esto el valor nulo para este tipo" (digamos, #define IntNull 4444444 y esperar que algún cálculo nunca lo devuelva accidentalmente), pero no hay un valor nulo real.

En el caso de CGRect en particular, Apple usó la táctica de "elegir un valor arbitrario" y definió CGRectNull, pero las variables de CGRect no están configuradas de manera predeterminada; debe configurarlo usted mismo.De forma predeterminada, las variables de instancia de CGRect se establecen en CGRectZero, pero recuerde que esta es solo una estructura de CGRect normal en la ubicación (0,0) con 0 ancho y 0 alto. Y los CGRects locales en una función tienen un valor totalmente impredecible.

5

De CGGeometry.h:

/* Return true if `rect' is empty (that is, if it has zero width or height), 
    false otherwise. A null rect is defined to be empty. */ 

un rectángulo vacío es aquel que no tiene zona, donde el o los dos lados son iguales a cero.
usar en su lugar:

CGRect newRect = CGRectNull; 
2

se puede envolver en CGRect NSValue también:

[NSValue valueWithCGRect:CGRectMake(x, y, width, height)]

Y entonces evitar el valor nil.

Cuestiones relacionadas