trucos texto puedo mensajes mensaje imensajes enviar entregado eliminar desde definitivamente como ios objective-c memory-management xcode4 opentok

ios - texto - mensaje no entregado iphone



Mensaje enviado a una instancia desasignada (7)

Cerrar la sesión de viewWillDisappear() funciona si puede determinar con certeza si la vista se viewWillDisappear() no se viewWillDisappear() . Algunas respuestas sugieren poner este código en dealloc() . Con respecto a esas sugerencias, Apple dice :

Debería intentar evitar administrar la vida útil de recursos limitados utilizando dealloc.

Por lo tanto, aquí es cómo puede determinar con certeza si su vista aparecerá. viewWillDisappear() cuando la vista se saca de la pila, o de lo contrario se presiona en otro lugar. Esta es la forma más fácil de determinar cuál, y luego anular la publicación / desconexión si realmente se ha reventado. Puede probar esto con isMovingFromParentViewController . Además, aquí es donde puedes eliminar observadores específicos.

- (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated] // This is true if the view controller is popped if ([self isMovingFromParentViewController]) { NSLog(@"View controller was popped"); // Remove observer [[NSNotificationCenter defaultCenter] removeObserver:self.session]; ... //dispatch_async(self.opentokQueue, ^{ if(self.subscriber){ [self.subscriber close]; self.subscriber = nil; } if (self.publisher) { [self doUnpublish]; } if (self.session) { [self.session disconnect]; self.session = nil; } //}); [self doCloseRoomId:self.room.roomId position:self.room.position]; } else { NSLog(@"New view controller was pushed"); } }

Ref .: Prueba de tipos específicos de transición de vista

Fondo:

Todos mis métodos OpenTok están en un ViewController que se pone a la vista, como una típica relación maestro / detalle de VC. El detailVC lo conecta a una sala diferente según su selección. Cuando presiono el botón Atrás para hacer estallar la vista, recibo un bloqueo (tal vez 1 de cada 7 veces):

[OTMessenger setRumorPingForeground] message sent to deallocated instance xxxxx

o

[OTSession setSessionConnectionStatus:]: message sent to deallocated instance 0x1e1ee440

Puse mis métodos de anulación de publicación / desconexión en viewDidDisappear:

-(void)viewDidDisappear:(BOOL)animated{ //dispatch_async(self.opentokQueue, ^{ [self.session removeObserver:self forKeyPath:@"connectionCount"]; if(self.subscriber){ [self.subscriber close]; self.subscriber = nil; } if (self.publisher) { [self doUnpublish]; } if (self.session) { [self.session disconnect]; self.session = nil; } //}); [self doCloseRoomId:self.room.roomId position:self.room.position]; }

Aquí hay un rastro:

Aquí está el DetailViewController en Github: enlace aquí

Cómo reproducirse:

  1. Realice una selección desde MasterVC, que lo llevará a DetailVC, que inmediatamente intenta conectarse a una sesión y publicar

  2. Regrese al anterior, MasterVC rápidamente, generalmente antes de que la sesión haya tenido la oportunidad de publicar una transmisión

  3. Pruebe esto varias veces y eventualmente se bloqueará.

  4. Si reduzco la velocidad y le doy la oportunidad al editor de conectarse y publicar, es menos probable que cause un bloqueo.

Resultado Esperado:

Debería simplemente desconectarse de la sesión / anular la publicación e iniciar una nueva sesión a medida que avanzo y retrocedo entre Master / DetailVC.

Otro:

¿Cuál es su dispositivo y versión del sistema operativo? ios 6

¿En qué tipo de conectividad estabas? Wifi

Zombies habilitados? Sí

¿ARC habilitado? Sí

Los delegados configurados a nil? Sí, por lo que sé

Cualquier ayuda para resolver este choque sería muy apreciada. Quizás me estoy perdiendo algo básico que simplemente no puedo ver.

Lo que parece suceder es que el objeto OTSession en la biblioteca OpenTok continúa enviando mensajes a objetos en esa biblioteca que desde entonces han sido desasignados al cambiar de vista. La biblioteca tiene un método [de desconexión de la sesión] que funciona bien si le da tiempo suficiente, pero tarda cerca de 2-3 segundos, y eso es mucho tiempo para pausar una aplicación entre vistas.

Esta podría ser una pregunta estúpida, pero: ¿hay alguna forma de detener todos los procesos iniciados por un cierto VC?


De acuerdo con el seguimiento de la pila que ha publicado, el centro de notificación llega a una instancia de OTSession que aún está activa. Posteriormente, esta instancia provoca métodos de llamada de bloqueo en objetos desasignados. Agregando a eso los dos mensajes de instancia desasignados diferentes, sabemos que hay eventos asincrónicos que ocurren después de la muerte de algunos objetos que desencadenan el bloqueo aleatorio que está teniendo.

Como sugirió ggfela, debe asegurarse de anular los delegados que ha conectado a OpenTok Framework. Le sugiero encarecidamente que haga eso en el método dealloc, ya que queremos asegurarnos de que, después de ese punto, nadie tenga referencias pendientes sobre su objeto:

- (oneway void)dealloc { self.session.delegate = nil; self.publisher.delegate = nil; self.subscriber.delegate = nil; }

Otra cosa extraña en el código es que su controlador para sessionDidConnect: crea una nueva dispatch_queue cada vez que se llama para llamar a doPublish :. Esto significa que tiene subprocesos simultáneos que comparten la instancia SROpenTokVideoHandler que los hace propensos a las condiciones de carrera.


Debe llamar a [super viewDidDisappear: animate]; al principio. Puede ser que arregle su problema. Y mejor limpie su sesión y suscriptor en el método dealloc:

- (void) dealloc { [self.session removeObserver:self forKeyPath:@"connectionCount"]; if(self.subscriber){ [self.subscriber close]; self.subscriber = nil; } if (self.publisher) { [self doUnpublish]; } if (self.session) { [self.session disconnect]; self.session = nil; } [self doCloseRoomId:self.room.roomId position:self.room.position]; //[super dealloc]; //for non-ARC }



La mayoría de las veces coloco un código en la vista Desaparecer, pero supongo que eso realmente no importa.

Creo que el problema es que el delegado de la sesión no está configurado en cero. Simplemente agregue lo siguiente en su viewDidDisappear:

self.session.delegate=nil;


Parece que OpenTok tiene un error con el uso NSNotificationCenter dentro de las clases OTSession y OTMessenger . Puede ver que estas clases en call-stack están separadas por llamadas a NSNotificationCenter :

Puede OTSession la suscripción manual de su objeto OTSession cuando dealloc (espero que OpenTok use defaultCenter ):

- (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self.session]; }

dealloc verificar si este código ( dealloc ) se ha ejecutado realmente. De lo contrario, debe solucionar el problema de la desasignación de UIViewController . Muchas otras respuestas contienen consejos sobre cómo ayudar a UIViewController a ser desasignado.


-(void)viewDidDisappear:(BOOL)animated cada vez que se oculta la vista, no solo cuando se extrae de la pila de la vista.

Entonces, si presiona una vista sobre él, se viewWillDisappear y se borrarán sus objetos.

Esto es especialmente problemático si carga estos mismos objetos desde viewDidLoad: lugar de viewDidAppear:

Quizás -(void)dealloc poner tu código de desconexión / desconexión en -(void)dealloc .