delegate crash con EXC_BAD_ACCESS

Tengo delegado

@property (nonatomic, assign) id <DelegateProtocol> delegate; 

pero falla en performSelector

 if (_delegate != nil && [_delegate conformsToProtocol:@protocol(DelegateProtocol)]) { NSObject *obj = _delegate; //HERE IS EXC_BAD_ACCESS [obj performSelectorOnMainThread:@selector(didTouchImageView:) withObject:self waitUntilDone:NO]; } 

Configuro delegado aquí:

 - (void)viewDidLoad { [super viewDidLoad]; [invoiceTabImage setDelegate:self]; } 

y la pregunta es por qué podría serlo.

EXC_BAD_ACCESS significa que su delegado ya fue desasignado cuando le envió el post didTouchImageView (supongo que todo está bien cuando envía el post performSelector , sería demasiado fácil).

En primer lugar, compruebe la gestión de retención / liberación de su delegado para ver si hay algo incorrecto.

Si todo parece estar bien, una posibilidad de depurar esto es habilitar Zombies (puede hacerlo a través de Instruments / Run con la herramienta de performance, o configurando una variable de entorno al depurar).

Esto podría ayudarlo a detectar la causa del problema.

Si necesita más ayuda, publique el código sobre cómo crea / retiene / libera su object de delegado y también pegue el rastreo de stack del locking.

EDITAR:

Dos pistas:

  1. la key para trabajar con delegates (sin retenerlos) es asegurarse de que el controller de vista (que en su caso también es el delegado) viva más que la invoiceTabImage ; luego puede revisar el ciclo de vida de invoiceTabImage (cuando se crea / libera) y compararlo con el del delegado;

  2. en el controller de su controller, agregue esta línea:

    invoiceTabImage = nil ;

    para que se asegure que cuando se quita el controller / delegado, el object delegado sabe que el delegado ya no está allí; el progtwig no funcionará, pero posiblemente no se bloquee.

Simplemente compruebe si se establece en nil (que es lo que hará desocuploc).

Esto resolvió mi problema:

 - (void)setDelegate:(id<UITableViewDelegate>)newDelegate { if (newDelegate!=nil) { if (newDelegate != self.collapseDelegate) { self.collapseDelegate = newDelegate; [super setDelegate:self.collapseDelegate?self:nil]; } } }