2012-04-01 5 views
8

He leído debajo de la pregunta, y la historia PARECE simple:¿Qué es "super" en Objective-C? (¡sí! = super)?

What exactly is super in Objective-C?

embargo ...

- (id) init 
{ 
    NSLog(@"self=%p, super=%p", self, super); 
} 

que imprime "auto = 0xa83dc50, super = 0xbfffe8d0" . Las direcciones NO SON LAS MISMAS ???!?!?

Esa segunda dirección parece ser un "valor especial" o algo así. Qué significa eso?

Gracias a bbum por señalar que este valor es la dirección de pila de una estructura especial utilizada por el compilador para implementar el comportamiento "super".


puedo llamar [súper init] y la llamada parece funcionar, o al menos, nada explota ... no inmediatamente. Llamar a [((id) 0xbfffe8d0) init] falla mucho con EXC_BAD_ACCESS.

Luego está la parte REALMENTE EXTRAÑA ..... Tengo un fragmento de código que, por ningún motivo explicable, arroja una excepción "NSGenericException: la colección fue mutada mientras estaba enumerada". Dentro de un objeto DIFERENTE (básicamente un contenedor que tiene un puntero al NSEnumerator), al comentar la llamada a "[super init]" no se produce la excepción. Si pudiera, pondría una recompensa de $$$ por una respuesta a ESO.

"id sups = (id) 0xbfffe8d0" ... que también conduce a "la colección está modificada". ... ¿WTF? Ok, así que les dejo una segunda pregunta para que bizzariotity ...


originalmente Vine aquí con una de esas "extrañas" symtoms insectos, que resultaron ser del todo ajeno (típico de este tipo de cosas) : Does casting an address to (id) have side-effects??? Is Address 0xbfffe8d0 special? (fixed: issue was with _NSCallStackArray)

Sin embargo, el contenido sobre la línea sigue siendo válido y la respuesta sigue siendo excelente. Léelo si quieres entender ObjC un poco más profundo.

+2

Aparte de sus otros problemas, 0xbfffe8d0 es presuntamente una dirección de código, pero no hay ninguna razón para esperar que sea la misma de una compilación a la siguiente. Lanzar ese valor literal a un puntero es básicamente crear un puntero a partir de un número aleatorio. –

+0

En realidad, es una dirección de pila, que no es lo mismo que una dirección de código. ¡No es lo mismo de una carrera a la siguiente! –

+0

Una dirección de pila no es la misma de un instante al siguiente en la misma ejecución. –

Respuesta

15

Usted está ensuciando con el hombre detrás de la cortina y él le está castigando por ello ... :)

super es un poco de magia compilador, de verdad. Cuando diga [super doSomething], el compilador emitirá una llamada a objc_msgSendSuper() en lugar de objc_msgSend(). La mayoría de las veces, hay algunos casos especiales.

En general, debe tratar super como solo un destino para las llamadas al método. Nunca se debe almacenar en ningún lugar y nunca se debe considerar nada como , sino como expresión de destino para mensajería.

De hecho, los usos de super que implican almacenamiento probablemente deberían ser marcados por el compilador.

En términos de su error, eso suena como si hubiera corrupción de la memoria, una sobreexpresión y/o concurrencia. Tendrá que proporcionar más código relacionado con la enumeración y otro código relevante para deducir más.

+0

heh, "meterse con el hombre detrás de la cortina" :) Publiqué una segunda pregunta con más detalles sobre ese error. –

+6

Si está interesado, 'super' se implementa (o solía ser) como un puntero a una estructura. La estructura contenía dos elementos, el primero de los cuales era 'self', y el segundo era la superclase, que le indica al tiempo de ejecución qué clase comenzar a buscar. – ughoavgfhw

+0

¡AH! Eso explica el extraño valor. Es la dirección de pila de esa estructura funky que mencionas. –