Re: occasional crash in AudioQueueStop()
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