2010-03-04 12 views
18

Cada vez que presiona un controlador de vista en mi pila, a continuación, el pop fuera, me sale este error:enviado a desasignado ejemplo

*** -[CALayer retainCount]: message sent to deallocated instance <memory address> 

Parece ocurrir justo después de dealloc se llama en el controlador de vista que se está Apareció y es exclusivo solo para este controlador de vista. Estoy seguro de que el CALayer tiene algo que ver con la vista en sí, ya que no los uso.

¿Alguna idea?

Editar: Aquí está la traza

(gdb) bt 
#0 0x01fcd3a7 in ___forwarding___() 
#1 0x01fa96c2 in __forwarding_prep_0___() 
#2 0x01fc10e8 in CFGetRetainCount() 
#3 0x01cbc770 in CA::release_root_if_unused() 
#4 0x01cbc707 in x_hash_table_remove_if() 
#5 0x01cbc4ec in CA::Transaction::commit() 
#6 0x01cc4838 in CA::Transaction::observer_callback() 
#7 0x01fa5252 in __CFRunLoopDoObservers() 
#8 0x01fa465f in CFRunLoopRunSpecific() 
#9 0x01fa3c48 in CFRunLoopRunInMode() 
#10 0x027dd615 in GSEventRunModal() 
#11 0x027dd6da in GSEventRun() 
#12 0x0057cfaf in UIApplicationMain() 
#13 0x00002dec in main (argc=1, argv=0xbfffeed0) 
+1

Indique el código donde exactamente está recibiendo este bloqueo. Y si sabe cómo usar NSZombieEnabled breakpoint y luego usarlo, obtendrá una idea de cuál podría ser el motivo de nuestro bloqueo. – Manjunath

+2

@Man: "mensaje enviado a instancia desasignada" significa que Zombie ya está habilitado. – kennytm

+0

El problema es que no hay un código donde se bloquea, puedo hacer un seguimiento. – skylerl

Respuesta

0

tengo la sospecha de que tiene que ver con la piscina de liberación automática ...

12

tuve problema similar; resulta que no estaba conservando un UIButton correctamente. Cómo encontré la causa: - Habilitar zombies - Ejecutar el proyecto con el instrumento 'Allocation' - Usar la aplicación para activar el error - Verificar que los instrumentos muestren el mensaje 'Zombie Messaged' en la línea de tiempo - Debe haber un enlace que abre los detalles de CALayer: cuando fue asignado y desasignado - Estás interesado en el lugar donde se asignó, debería ser que aha !!! coloque en su código

¡Buena suerte!

+0

He hecho esto y la línea donde dice que CALayer estaba malloc'd es '[[NSBundle mainBundle] loadNibNamed @" ... "' etc. Lo cual no ayuda porque he pasado por esa punta muchas veces y nada está siendo destrabado dos veces. –

4

Tuve un problema similar. Mi problema era que una de las variables de objeto declaradas en la interfaz se declaró erróneamente con (nonatomic, assign) y no como (nonatomic, retain), como debería haber sido. Esto provocó que se enviara un mensaje de liberación a un objeto que ya tenía un conteo retenido de 0 (= crash).

7

Esto es un poco complicado, el mío era un lanzamiento doble en una función dealloc de una de las clases (m/xib) que tenía en una vista de tabla como estilo de fila. Los instrumentos no mostraron mucho sobre el objeto, pero la comprobación de la pila de llamadas fue realmente útil para identificar qué clase era la que iba a -1.

Sample

+0

¿Cuándo dices que fue un lanzamiento doble en una función dealloc de una de las clases (m/xib) quieres decir que estuviste lanzando en un archivo am y también en un archivo XIB? Tengo un problema similar: UIView cargó a través de un XIB con su subclase UIView personalizada. En mi subclase UIView estoy desasignando una propiedad y se bloquea con el mismo error que tiene. Si la comento, todo está bien. ¿Es posible? incluso desasociar en un XIB? –

+0

Me encontré con este error y también se debió a que un IBOutlet se lanzó dos veces. Se parecía a [lanzamiento de myLabel]; [lanzamiento de myLabel]; (literalmente uno al lado del otro). Su mejor práctica es asigna la variable a cero después de la liberación, que no se hizo aquí o th El error no se habría manifestado. Difícil de rastrear, pero afortunadamente el código para este controlador de vista era bastante pequeño. – Sam

+0

Esto es muy útil. Gracias. – teepusink

3

I tenían el mismo error y que era porque creé una UIButton utilizando buttonWithType (por ejemplo [UIButton buttonWithType:UIButtonTypeRoundedRect]) y liberado posteriormente. Esto fue incorrecto porque buttonWithType ya tiene un autorelease incluido. Así que eliminé mi release y el error desapareció.

0

Me estaba saliendo el mismo error. Hice un objeto UIView para mantener dos botones, que luego agregué al elemento de navegación rightBarButtonItem. El problema es que utilicé el método de fábrica buttonWithType para crear los botones, pero acabo de alloc y initWithFrame mi vista. Luego, cuando terminé con la vista, la liberaba y más tarde, cuando el sistema intentaba liberar los dos botones (subvistas del ya publicado UIView) - bloqueo - Estaba enviando un mensaje a los botones ya publicados. Espero que ayude a alguien a ahorrar algo de tiempo en problemas similares.

+1

¿cómo adivinas esto? –

1

¡Seguir la vista es realmente útil! Puede ser bastante trivial si conoces el marco y qué superlayers y sublayers se relacionan con esa vista ... Si registras todas las capas es solo para buscar y encontrar esa misma dirección de memoria. ¡Buena suerte!:)

Añadir esta categoría a su aplicación

Categoría-Header:

#import "CALayer+debug.h" 

@interface CALayer (Debug) 

-(NSString*)debugDescription; 
-(NSString*)debugLayerTree; 

@end 

Categoría-Implementación:

#import <Foundation/Foundation.h> 
#import <QuartzCore/QuartzCore.h> 
#import "CALayer+debug.h" 
#import <UIKit/UIKit.h> 
#import <objc/runtime.h> 
#import <objc/message.h> 


@implementation CALayer (Debug) 

//.... 

void Swizzle(Class c, SEL orig, SEL new) 
{ 
    Method origMethod = class_getInstanceMethod(c, orig); 
    Method newMethod = class_getInstanceMethod(c, new); 
    if(class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) 
     class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod)); 
    else 
     method_exchangeImplementations(origMethod, newMethod); 
} 

+ (void)swizzle { 
    Swizzle([self class], @selector(init), @selector(newInit)); 
} 

- (id)newInit { 
    self = [self newInit]; 

    [self performSelector:@selector(log) withObject:self afterDelay:0.5]; 

    return self; // calls old method 
} 

- (void)log { 
    NSLog(@"%@", [self debugDescription]); 
} 

- (NSString *)debugDescription { 
    return [NSString stringWithFormat:@"%@ frame=%@ zAnchor=%1.1f, superlayer: %@>", [self description], NSStringFromCGRect(self.frame), self.zPosition, self.superlayer]; 
} 


@end 

llamada desde, por ejemplo, appdelegate

[CALayer swizzle]; 
+0

Esta es realmente una gran manera de depurar. ¡Gracias! – nonamelive

Cuestiones relacionadas