2010-08-12 16 views

Respuesta

17

CFGetTypeID():

if (CFGetTypeID(myObjectRef) == CFStringGetTypeID()) { 
    //i haz a string 
} 
+1

Sí, ¿qué hay del resto de CFTypes? Hay muchos de ellos, no puedo hacerlo para cada uno. –

+0

En realidad, era una cadena. –

9

La respuesta corta es que se puede (véase la respuesta de Dave DeLongs). La respuesta larga es que no puedes. Ambos son verdaderos Una mejor pregunta podría ser "¿Por qué necesitas saber?" En mi opinión, si puedes arreglar las cosas para que no necesites saber, probablemente estarás mejor.

No estoy diciendo que no pueda hacerlo, o incluso que no deba hacerlo. Lo que estoy diciendo es que hay algunos obstáculos escondidos cuando comienzas por este camino, y algunas veces no eres realmente consciente de cuáles son todas las suposiciones no declaradas. Desafortunadamente, la programación correctamente depende de conocer todos los pequeños detalles. De la parte superior de mi cabeza, he aquí algunas de las trampas potenciales:

  • A lo mejor de mi conocimiento del conjunto de tipos de fundación de la base se ha incrementado en cada versión principal del sistema operativo. Por lo tanto, cada versión principal del sistema operativo tiene un superconjunto de tipos de Fundamentos básicos de las versiones anteriores, y probablemente un superconjunto estricto. Esto es "comportamiento observado", y no necesariamente un comportamiento "garantizado". Lo importante a tener en cuenta es que "las cosas pueden cambiar y lo hacen" y, en igualdad de condiciones, las soluciones más sencillas y sencillas tienden a no tener esto en cuenta. En general, se considera que un estilo de programación deficiente para codificar algo que se rompe en el futuro, independientemente de la razón o la justificación.

  • Debido a Bridging de llamada gratuita entre la Fundación y la Fundación Core, sólo porque un CFTypeRef = CFStringRef no quiere decir que un CFTypeRef ≡ CFStringRef, donde = significa "igual" y significa "idéntico". Hay una distinción, que puede o no ser importante según el contexto. Como advertencia, esto tiende a ser donde los errores se mueven libremente.

    Por ejemplo, se puede usar un CFMutableStringRef donde se pueda usar CFStringRef, o CFStringRef = CFMutableStringRef. Sin embargo, no puede usar un CFStringRef dondequiera que se pueda usar CFMutableStringRef por razones obvias. Esto significa CFStringRef ≢ CFMutableStringRef. De nuevo, dependiendo del contexto, pueden ser iguales, pero no son idénticos.

    Es muy importante tener en cuenta que, si bien hay un CFStringGetTypeID(), no hay CFMutableStringGetTypeID() correspondiente.

  • Lógicamente, CFMutableStringRef es un superconjunto estricto de CFStringRef. De esto se desprendería que pasar una buena inmutable CFStringRef a una llamada a la API CFMutableString causaría "algún tipo de problema". Si bien esto puede no ser cierto ahora (es decir, 10.6), sé con certeza que lo siguiente fue cierto en el pasado: las llamadas a la API CFMutableString no verificaron que "el argumento de la cadena" fuera realmente mutable (esto fue cierto para todos tipos que hacían una distinción entre inmutable y mutable). Los controles estaban allí, pero estaban en forma de afirmaciones de depuración que estaban deshabilitadas en las compilaciones de "Liberación" (en otras palabras, los controles nunca se realizaron en la práctica).

    Esto es (o posiblemente fue) oficialmente no se considera que es un error, y los triviales () mutabilidad cheques eran no hecho "por razones de rendimiento". No se proporciona API "pública" para indicar la mutabilidad de un puntero CFString (o mutabilidad de cualquier tipo). Combinado con el puenteo sin cargo, esto significaba que podía mutar los objetos inmutables NSString, aunque las API NSMutableString realizaban un control de mutabilidad y causaban "algún tipo de problema" al intentar mutar un objeto inmutable. Sabor con el hecho de que @"" cadenas constantes en su fuente se asignan a la memoria de solo lectura en tiempo de ejecución.

    La línea oficial, según recuerdo, era "no pasar objetos inmutables, ya sea CFStringRef o NSString, a la API de CFMutableString, y más, era un error hacerlo". Cuando se señaló que podría haber algunos problemas de seguridad relacionados con esta postura (sin importar el hecho de que era fundamentalmente imposible), di si alguna vez cometieron el error de depender críticamente de la inmutabilidad de una cuerda, especialmente "bien conocida". cadenas, la respuesta fue "el problema es teórico y no se hará nada en este momento hasta que se pueda demostrar un exploit viable".

    Actualización: Tenía curiosidad por ver cuál es el comportamiento actual. En mi máquina, ejecutando 10.6.4, usando CFMutableString API en un CFString inmutables, la cadena inmutable se convierte esencialmente en @"", que es al menos mejor que antes (< = 10.5) y realmente muta la cadena. Definitivamente no es la solución ideal, tiene ese sabor amargo del mundo real donde su única cualidad redentora es que es "la peor solución".

Así que recuerda, ¡ten cuidado en tus suposiciones! Puede hacerlo, pero si lo hace, es más importante que no hágalo incorrecto. :) Por supuesto, muchas soluciones "incorrectas" funcionarán, por lo que el hecho de que las cosas funcionen no es necesariamente una prueba de que lo estás haciendo bien. ¡Buenos tiempos!

Además, en un sistema Duck Typed a menudo se considera de mala calidad, y posiblemente incluso un error, "mirar demasiado de cerca el tipo de objeto". Objective-C es definitivamente un sistema Duck Typed y sin lugar a dudas se desborda en Core Foundation debido al estrecho acoplamiento de los puentes gratuitos. CFTypeRef es una manifestación directa de esta ambigüedad tipo Pato, y dependiendo en gran medida del contexto, puede ser una forma explícita de decir "No se supone que mires demasiado de cerca a los tipos".

+0

guau, esa es una respuesta larga. +1 –

+1

La razón por la que necesito saber es porque recupero una propiedad del registro IO que puede ser una cantidad de cosas y no puedo determinar cuál es. –

0

Si desea saber qué tipo es CFTypeRef durante el desarrollo, puede usar el siguiente fragmento de código.

printf("CFTypeRef type is: %s\n",CFStringGetCStringPtr(CFCopyTypeIDDescription(CFGetTypeID(myObjectRef)),kCFStringEncodingUTF8)); 

Esto imprimirá un nombre legible para el tipo para que sepa de qué se trata. Pero Apple no garantiza que mantendrán estas descripciones consistentes, así que no lo use en el código de producción. (Como es el fragmento, perderá memoria pero solo debería usarlo durante el desarrollo, así que ¿a quién le importa?).

Cuestiones relacionadas