Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Message sent to a deallocated instance

Tags:

Background:

All my OpenTok methods are in one ViewController that gets pushed into view, like a typical Master/detail VC relationship. The detailVC connects you to a different room depending on your selection. When I press the back button to pop the view away, I get a crash (maybe 1 out of 7 times):

[OTMessenger setRumorPingForeground] message sent to deallocated instance xxxxx 

or

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

I put my unpublish/disconnect methods in 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]; } 

Here is a trace:

Image

Here is the DetailViewController on Github: link here

How to reproduce:

  1. Make a selection from the MasterVC, that takes you into the DetailVC which immediately attempts to connect to a session and publish

  2. Go back to previous, MasterVC quickly, usually before the session has had an a chance to publish a stream

  3. Try this several times and eventually it will crash.

  4. If I slow down and allow the publisher a chance to connect and publish, it is less likely to cause a crash.

Expected result:

It should just disconnect from the session/unpublish and start a new session as I go back and forth between the Master/DetailVC's.

Other:

What is your device and OS version? iOS 6

What type of connectivity were you on? wifi

Zombies Enabled? Yes

ARC Enabled? Yes

Delegates set to nil? Yes, as far as I know

Any help solving this crash would be greatly appreciated. Perhaps I'm missing something basic that I just can't see.

What seems to happen is that the OTSession object in the OpenTok library continues to to send messages to objects in that library that have since been deallocated by switching views. The library has a [session disconnect] method that works fine if you give it enough time, but it takes close to 2-3 seconds, and that's a long time to pause an app between views.

This might be a stupid question, but: Is there anyway to stop all processes initiated by a certain VC?

like image 410
Emin Israfil Avatar asked Aug 14 '13 04:08

Emin Israfil


1 Answers

Closing the session from viewWillDisappear() works if you can determine for sure that the view is going to be popped, not pushed or hidden. Some answers suggest putting this code in dealloc(). Regarding those suggestions, Apple says,

You should try to avoid managing the lifetime of limited resources using dealloc.

So, here is how you can determine for sure that your view will get popped. viewWillDisappear() is called when the view is popped from the stack, or is otherwise pushed somewhere else. This is the easiest way to determine which, and then unpublish/disconnect if it is truly popped. You can test for this with isMovingFromParentViewController. Also, here is where you can remove specific observers.

- (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: Testing for Specific Kinds of View Transitions

like image 117
Drakes Avatar answered Nov 10 '22 18:11

Drakes