• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: occasional crash in AudioQueueStop()
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: occasional crash in AudioQueueStop()


  • Subject: Re: occasional crash in AudioQueueStop()
  • From: Brian Willoughby <email@hidden>
  • Date: Fri, 17 Oct 2008 15:29:34 -0700

Chris, it seems that you're a victim of bad advice from the internet. What you are calling "common practice" is a bad practice. I Googled 'retain delegate' and found some really bad code. It seems that newcomers to Cocoa are learning bad habits and then spreading these around. I have been writing and releasing Cocoa code since 1991, and I have never found a reason to violate the rule that all object references should be retained or set to nil. The fact that an object reference happens to be a delegate object is no reason to ignore this rule.

To put it in perspective, your callback is sending a message to a delegate object which disappears unpredictably. That shows a fundamental problem. Your reluctance to retain the delegate object for the duration of time that your callback is in place, citing retain loops as an excuse, shows that there is a design flaw in your object graph as well. But it's your code, and you can hack it up however you please.

My point is that not every program design will suffer from the object graph cycle problems that your code has. Therefore, recommending retain and release calls inside a callback is not good general advice. I realize that you're reciting advice that you've read elsewhere, but it's bad advice that you received nonetheless.

One very important problem with your design is that you should avoid allocating or freeing memory inside a callback. While retain does not allocate memory, release can easily free memory. Moving retain/ release outside the callback register/deregister solves this issue, and also makes your callback have lower overhead.

The best advice is to retain the delegate object before you register any callback which uses that delegate object, and then release the delegate afterwards. There are many ways to organize your code to achieve this goal, and if you end up with a retain cycle then you should look elsewhere for a fix.

Brian Willoughby
Sound Consulting


On Oct 17, 2008, at 13:08, Christopher Liscio wrote: I'm not sure that's the best solution, Brian.

In the case you suggest, it would work provided the releasing of the delegate (and the teardown of the callback) is done outside of the dealloc call.

In my case, the delegate of the audio queue object in question owns a reference to the audio queue object, and this retain strategy you suggest would result in a retain cycle, since I tear down the callback in the dealloc call (as most likely would).

It's common practice to not retain a delegate to avoid retain cycles like this, and I try to stick to that as a general rule of thumb in my code.

The retain 'fix' I proposed isn't meant to be slapped onto every call to a delegate--only the calls made within CoreAudio callbacks that can be invoked outside the main run loop.

Chris Liscio
http://SuperMegaUltraGroovy.com
Acoustic measurement software for Mac OS X -- http://www.FuzzMeasure.com

On Oct 17, 2008, at 3:09 PM, Brian Willoughby wrote:
The suggested retain/release is the right solution in the wrong place. You don't want to surround every single delegate call with a retain and release. Instead, you want to call retain before you set up your callback, to make sure that your delegate object lives as long as your callback. Then, if you ever tear down your callback (which is pretty unlikely if the callback lives for the duration of your program), you should call release after the callback has been successfully removed.

There are ways to make this a little easier by altering the way you allocate and initialize your delegate object, but I won't get into that here. Basically, I just wanted to touch on enough Cocoa to get folks sorted for their CoreAudio callbacks.
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


  • Follow-Ups:
    • Re: occasional crash in AudioQueueStop()
      • From: Christopher Liscio <email@hidden>
References: 
 >occasional crash in AudioQueueStop() (From: John Zorko <email@hidden>)
 >Re: occasional crash in AudioQueueStop() (From: Christopher Liscio <email@hidden>)
 >Re: occasional crash in AudioQueueStop() (From: Brian Willoughby <email@hidden>)
 >Re: occasional crash in AudioQueueStop() (From: Christopher Liscio <email@hidden>)

  • Prev by Date: Re: NSSlider correct event handling in Audio Unit with Cocoa GUI
  • Next by Date: Re: occasional crash in AudioQueueStop()
  • Previous by thread: Re: occasional crash in AudioQueueStop()
  • Next by thread: Re: occasional crash in AudioQueueStop()
  • Index(es):
    • Date
    • Thread