Objeto desasigna inmediatamente después de haber sido inicializado

Estoy intentando hacer una class que reproduzca videos de YouTube, pero tengo varios problemas con ella.

Aquí está mi class que maneja los videos de YouTube:

// this is the only property declanetworking in the .h file: @property (strong, nonatomic) UIView * view // the rest of this is the .m file: #import "MyYouTube.h" @interface MyYouTube() @property (strong, nonatomic) NSDictionary * contentData; @property (strong, nonatomic) UIWebView * webView; @property (nonatomic) int videoOffset; @end @implementation MyYouTube @synthesize view,contentData,webView,videoOffset; - (MyYouTube*) initIntoView: (UIView*) passedView withContent: (NSDictionary*) contentDict { NSLog(@"YOUTUBE: begin init"); self=[super init]; videoOffset=0; view=[[UIView alloc] initWithFrame:passedView.bounds]; [view setBackgroundColor:[UIColor blackColor]]; [view setAutoresizesSubviews:YES]; [view setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth]; contentData=contentDict; NSString * compiledUrl=[[NSString alloc] initWithFormat:@"http://_xxx_.com/app/youtube.php?yt=%@",[contentData objectForKey:@"cnloc"]]; NSURL * url=[[NSURL alloc] initWithString:compiledUrl]; NSURLRequest * request=[[NSURLRequest alloc] initWithURL:url]; webView=[[UIWebView alloc] initWithFrame:passedView.bounds]; [webView loadRequest:request]; [webView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight]; [[webView scrollView] setScrollEnabled:NO]; [[webView scrollView] setBounces:NO]; [webView setMediaPlaybackRequiresUserAction:NO]; [webView setDelegate:self]; NSLog(@"YOUTUBE: self: %@",self); NSLog(@"YOUTUBE: delegate: %@",webView.delegate); [view addSubview:webView]; NSLog(@"YOUTUBE: end init"); return self; } -(void)webViewDidFinishLoad:(UIWebView*)myWebView { NSLog(@"YOUTUBE: send play command"); [webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"playVideo(%d)", videoOffset]]; } - (void) dealloc { NSLog(@"YOUTUBE: dealloc"); } @end 

Aquí está el código que llama a esta class (este código se encuentra en appDelegate):

 NSLog(@"about to load youtube"); ytObj=[[MyYouTube alloc] initIntoView:mainView withContent:cn]; NSLog(@"loaded youtube"); [mainView addSubview:[ytObj view]]; 

FYI mainView e ytObj se declaran así:

 @property (nonatomic,strong) UIView * mainView; @property (nonatomic,strong) MyYouTube * ytObj; 

Cuando se ejecuta este código, la aplicación se bloquea y obtengo esto en la console:

 about to load youtube YOUTUBE: begin init YOUTUBE: self: <MyYouTube: 0x16503d40> YOUTUBE: delegate: <MyYouTube: 0x16503d40> YOUTUBE: end init YOUTUBE: dealloc loaded youtube *** -[MyYouTube respondsToSelector:]: message sent to deallocated instance 0x166f19f0 

Si configuro el delegado de UIWebView a nil , la aplicación no se bloqueará, pero, como era de esperar, el video de YouTube no se reproducirá automáticamente.

¿Alguien me puede explicar:

  • ¿Por qué el object se desasigna inmediatamente después de haber sido inicializado?

  • ¿Por qué el post de respondsToSelector: ToSelector respondsToSelector: se envía a una instancia que no sea MyYouTube?

  • ¿Cómo puedo hacer que el video de YouTube se reproduzca automáticamente sin que se bloquee la aplicación?

Muchas gracias.


EDITAR

Totalmente mi malo – ytObj es una propiedad fuerte – Me olvidé de mencionar esto. He agregado el código para reflejar esto.


EDIT 2

He agregado un punto de interrupción en el método dealloc, y esta es la stack de llamadas:

 0 -[MyYouTube dealloc] 1 objc-object::sidetable_release(bool) 2 -[MyAppDelegate playYouTube:] 

La última input aquí ( playYouTube: es el método que contiene el código en mi delegado de la aplicación que se encuentra en la publicación original anterior. Entonces, una pregunta más:

  • ¿Qué es objc-object::sidetable_release(bool) , qué hace y por qué está liberando mi object de YouTube?

¿Por qué el object se desasigna inmediatamente después de haber sido inicializado?

Porque nada lo posee.

Lo configuró como delegado en una vista, pero la propiedad de delegado de UIWebView es una propiedad de assign . La vista no se hace responsable de su delegado. Esto significa que cuando ytObj sale del ámbito (posiblemente antes, dependiendo de la optimization), nada lo posee, por lo que desaparece.

EDITAR

También debes asegurarte de que cuando se desasigna un ytObj, configuras la propiedad de delegado de cualquier punto de vista, es un delegado de hasta cero. De lo contrario, las vistas continuarán intentando enviar posts al object desasignado.

¿Cómo puedo hacer que el video de YouTube se reproduzca automáticamente sin que se bloquee la aplicación?

ytObj asegurarse de que ytObj dure tanto como la vista del delegado y cuando se desasigne, el delegado de la vista se establece en nil.


Otro problema menor. Su function -init debería probar que el self no es nulo después de invocar self = [super init] . No debería ejecutar ninguno del rest del código de initialization si self es nulo.

1) (mi primera respuesta a tu primera pregunta, antes de tu edición)

Esto sucede porque está utilizando ARC (conteo automático de references) y no está manteniendo su variable local " ytObj " ((que NO es la propiedad " self.ytObj ") en el object en el que lo creó. Tan pronto como sea posible como la function que creó la variable " ytObj " local termina y regresa, el object se dispara automágicamente.

Cambia esto:

 ytObj=[[MyYouTube alloc] initIntoView:mainView withContent:cn]; 

a esto:

 self.ytObj=[[MyYouTube alloc] initIntoView:mainView withContent:cn]; 

Y para las "mejores prácticas", también sugiero no hacer tanto trabajo y / o código en el delegado de la aplicación. Los delegates de la aplicación deben recibir posts específicos de la aplicación (como "la aplicación está suspendiendo", "la aplicación vuelve a estar activa", etc.), y debería hacer cosas como esta en un controller de vista subclasificado.

2)

El error " respondsToSelector: " que estás viendo se debe a que tu object de YouTube se ha cancelado automágicamente. Si todavía estuviera vivo, no verías ese post.

3)

Si buscas aquí en Stackoverflow, encontrarás otras preguntas y respuestas que explican cómo hacer la reproducción automática … ¿y qué hay de esta?

El object ytObj dado que no está referencedo fuerte en ninguna parte, solo existe dentro del scope donde está definido. Los delegates la mayoría de las veces se declaran como properties débiles. Ninguno guarda una fuerte reference a este object, por lo que ARC lo libera.
Cree properties fuertes para ytObj y verá que todo funciona bien.