Sé que cuando queremos crear un objeto de valor desconocido usamos id. Sin embargo, tengo curiosidad por saber por qué Apple eligió el id, que decide su valor durante el tiempo de ejecución, cuando cada objeto es una subclase de NSObject. Entonces, en lugar de id delegate
podríamos haber usado NSObject *delegate
¿Alguien sabe por qué? Gracias.¿Por qué usar id cuando podemos usar NSObject?
Respuesta
id
borra el tipo y es equivalente a decir "este objeto responde a cualquier selector visible para la traducción". por supuesto, es su responsabilidad de asegurarse de que su programa sea correcto cuando borre los tipos (y también cuando los haya encasillado).
Si el tipo eran NSObject
, entonces el compilador diría "NSObject puede no responder a selector de" si el selector no fue declarado en la interfaz del NSObject o los protocolos que adopta. En ese caso, también puede agregar un tipocast para convertirlo al tipo que espera.
Con tipos estrictos/correctos, el compilador puede entrar en acción y ayudarte, lo que es genial porque ObjC es un lenguaje muy dinámico.
id
es particularmente útil al utilizar (o crear) tipos de colecciones. Agregar un objeto no sería un problema a menos que haya definido un nuevo tipo de raíz (no hereda de NSObject). Obtener un valor de la colección requeriría un encasillado si lo usáramos como algo más que nuestra clase base (NSObject).
Objective-C no admite genéricos: no puede, por ejemplo, declarar NSArray
de NSString
s. Puede llenar un NSArray
con NSString
sy pasarlo a través de id
para un estilo escrito más natural cuando no se conserva la seguridad del tipo (a la genéricos).
Por lo tanto, ampliemos esto con un código real.
Ejemplo A
NSString * string = [array objectAtIndex:0]; // << trust me (via id)
return [string length];
-or-
return [[array objectAtIndex:0] length]; // << trust me (via id)
Ejemplo B
Y ahora vamos a decir id
no está disponible y que soluciona todas nuestras advertencias del compilador porque es lo que hay que hacer:
NSString * string = (NSString*)[array objectAtIndex:0]; // << typecast == trust me
return [string length];
-or-
return [(NSString*)[array objectAtIndex:0] length]; // << typecast == trust me
id
no decide su valor en tiempo de ejecución, ni tampoco ningún objeto NSO. Los objetos ObjC no realizan promociones implícitas, simplemente lanzan el puntero sin una promoción formal.
relacionados con su ejemplo, que en realidad declaro mis delegados y parámetros como NSObjects con los protocolos:
NSObject<MONShapeDelegate>* delegate;
Puede diferir en otros compiladores que los que yo uso, pero hasta donde yo sé, si declaras un tipo como NSObject
@Aberrant si un método de delegado es opcional, corresponde al * que llama * verificar que el objeto responde al selector. – justin
Lo sé, es por eso que dije que el compilador supone que están implementados. Si no fuera así, los opcionales siempre causarían advertencias, ya que el compilador no puede estar seguro de si los objetos responderán en tiempo de ejecución. – Aberrant
cada objeto es una subclase de NSObject
Eso no es correcto. Podría hacer un objeto que se extienda desde la nada como una clase de raíz.
Esa es quizás la razón por la que se introdujo la identificación.
cada objeto es una subclase de NSObject
Esa es una declaración incorrecta. Puede crear objetos que no hereden de NSObject. no es realmente recomendable, pero es posible.
NSProxy
es un ejemplo: no hereda de NSObject.
¡Esto es solo una copia de mi respuesta! –
Lo siento:/Lo escribí cuando no había respuestas, me pegaste al golpe ... sin resentimientos y sin ninguna necesidad de un voto negativo ... Además, no mencionaste 'NSProxy' ... – Jasarien
Si es una pila y esta respuesta está en la parte inferior, entonces @Jasarien respondió en primer lugar;) – beryllium
typedef struct objc_object {
Class isa;
} *id;
Arriba está la definición real de id
en lenguaje Objective-C. El sistema de tiempo de ejecución Objective-C está construido alrededor de id
y Class
. Nada tiene que ver con NSObject o super clase común.
El NSObject Clase
NSObject es una clase raíz, y por lo tanto no tiene una superclase. Define el marco básico para objetos Objective-C e interacciones de objetos. Se imparte a las clases y las instancias de clases que heredan de la capacidad de comportarse como objetos y cooperar con el sistema de tiempo de ejecución .
Una clase que no necesita heredar ningún comportamiento especial de otra clase debe, sin embargo, convertirse en una subclase de la clase NSObject. Las instancias de la clase deben, como mínimo, tener la capacidad de comportarse como objetos Objective-C en tiempo de ejecución. Heredar esta capacidad de la clase NSObject es mucho más simple y mucho más confiable que reinventarlo en una nueva definición de clase.
pienso, esto es debido a que es un principio no C
C++
(u otros lenguajes de escritura mucho más estrictas).
- 1. ¿Por qué utilizar (id) en una firma de método cuando (NSObject *) sería más preciso?
- 2. ¿Por qué no podemos usar C-strings como SEL?
- 3. ¿Por qué no podemos usar assertion para métodos públicos?
- 4. ¿Por qué no podemos usar "herencia virtual" en COM?
- 5. ¿Por qué no podemos usar uniones externas en CTE recursivo?
- 6. ¿Por qué usar Jython cuando solo podías usar Java?
- 7. ¿Qué podemos usar en lugar de nstimer?
- 8. podemos usar CASE con EXEC
- 9. ¿Podemos usar & en url?
- 10. ¿Por qué usar NSFetchedResultsController?
- 11. ¿Por qué no debería usar ID de estilo con CSS?
- 12. Por qué usar (function() {....}());
- 13. Por qué usar NSObjectController
- 14. ¿podemos usar xpath con BeautifulSoup?
- 15. ¿Podemos usar union en hibernate?
- 16. ¿Podemos usar pom.xml en ANT
- 17. ¿Podemos usar Foundation con HTML5Boilerplate?
- 18. ¿Podemos usar $ (esto) con otro selector?
- 19. ¿Por qué usar NSAutoreleasePool?
- 20. ¿Por qué usar mysqli_close()?
- 21. Por qué usar scala.collection.immutable.Stack
- 22. ¿Por qué usar Mono?
- 23. ¿Por qué usar LabVIEW?
- 24. ¿Por qué usar hex?
- 25. ¿Por qué usar java.io.Console?
- 26. ¿Por qué usar document.write?
- 27. ¿Por qué usar Eventos?
- 28. ¿Por qué usar ThreadStart?
- 29. ¿Por qué usar DialogFragment?
- 30. ¿Por qué usar @PostConstruct?
NSProxy es otra clase raíz que suministra el cacao. –
NSObject contiene isa puntero, id no. Eche un vistazo a http://stackoverflow.com/a/19634973/944634 –
¿qué lol? id es un puntero isa http://stackoverflow.com/questions/1990695/in-cocoa-how-is-the-id-type-defined – TheAmateurProgrammer