EASession leaks

I have an application that connects to an accessory, and an EASession that I create to connect with accessory leaks when disconnecting the accessory.

When an accessory is connected, I receive a notification about this and check the EAAccessoryManager accessory collection for the accessory with a specific name that uses a specific protocol. When I find this, I create an EASession object for this accessory with code:

-(void) openSession { ... // finds accessory object if (accessory) { [self closeSession]; session = [EASession alloc]; NSLog(@"alloc :: session retainCount: %i", session.retainCount); [session initWithAccessory:accessory forProtocol:SmokeSignalsProtocolName]; NSLog(@"init :: session retainCount: %i", session.retainCount); [[session inputStream] open]; [[session outputStream] open]; ... // other logic (pump run loop, etc..) } } -(void) closeSession { if (session) { [[session inputStream] close]; [[session outputStream] close]; [session release], session = nil; } } 

Usually I have alloc and init on the same line, but what I found (dividing it like this) is that alloc gives +1 to keep the score (as you would expect) BUT iniWithAccessory:forProtocol: gives it a hold value + 3 when I would expect +2 saveCount from the init method.

The leak tool also supports this:

enter image description here

A step-by-step look at the leak tool:

  • +1 save count :: [???Accessory openSession] - here I highlight the new EASession.
  • +1 save count :: [EAInputStream iniWithAccessory:forSession:] The input stream returns a link to the ownership session.
  • +1 save count :: [EAOutputStream initWithAccessory:forSession:] The output stream returns a link to the ownership session.
  • +1 keep count :: [EASession iniWithAccessory:forProtocol:] I have no idea why this increases the number of EASession accounts. I believe that this is responsible for an additional retention rate, which I canโ€™t explain ... Not sure how it should be balanced. Is this Apple's mistake, and I need to call release extra time to balance things ... Very VERY weird.
  • -1 count count :: [EAInputStream close] Clears step # 2 above
  • -1 count count :: [EAOutputStream close] Clears step # 3 above
  • -1 count count :: ???Accessory closeSession] Clears step # 1 above1

So ... Why am I leaking an EASession object? What is the correct way to use an EASession object to leak?


Edit - EADemo is not a leak, but ...

EADemo connects to accessories, but it does not flow. Out of curiosity, I added an extra [_session retain] so that it leaked so that I could follow its history in tools. It was interesting to see some internal things that were not mentioned in the malloc history of my application.

enter image description here

You can see that it has [EAAccessoryInternal removeSession:] called 3 times. This has never been called up in the malloc history of my application. I think this is the key to why my EASession is not released ...

+6
source share
2 answers

I know this discussion is pretty old, but lately I had exactly the same problem using ARC etc I found that one way is to simply not close the input or output streams. Just use a class that processes all input etc and forwards the data on request to other parts of your application. You can reassign the EASession object without any claim from Xcode, so I assume the old EASession is freed up OK, because it no longer refers to my APP. However, I have not checked the leak yet.

+1
source

While the demo does the opposite, I managed to fix this leak by calling the input and output methods after , removing them from the run loop and setting their delegate to zero.

+1
source

Source: https://habr.com/ru/post/913984/


All Articles