Hello Jeremy,
On 3/11/2012 8:40 PM, jeremy.sagan wrote:
> I think you should (and I certainly do) unload bundles
OK.
> but because
> bundles may be in use for other plug-in types (VST/AU)
I'm not sure I follow you here. Can you clarify what you mean by "in use for other plug-in types" please?
> it is important
> (and mandatory on certain plug-ins, e.g. Korg) to do a check on the
> retain count.
Are you suggesting that some plugins retain their own bundle? Would you be able to give a specific Korg plugin as an example so I can test it?
I'm wondering whether in the code below your app is holding multiple references to the bundle, or whether you're only holding one and the other reference(s) are held by the plugin itself.
> Something like this:
>
> CFIndex retainCount = CFGetRetainCount(AHP->piBundle);
> if (retainCount == 1)
> {
> //Do other cleanup here if necessary
> CFBundleUnloadExecutable(AHP->piBundle);
> }
One thing I have noticed is that if you CFRelease a bundle when it's retain count is 1 it seems to get unloaded anyway.
I.e. releasing the last reference to a bundle automatically triggers CFBundleUnloadExecutable.
I guess if you want to keep the bundle handle around then calling CFBundleUnloadExecutable explicitly still makes sense.
https://developer.apple.com/library/mac/#documentation/CoreFOundation/Reference/CFBundleRef/Reference/reference.html
------------------------
CFBundleGetFunctionPointerForName
and related calls automatically load a bundle if it is not already
loaded. When the last reference to the CFBundle object is released and
it is finally deallocated, then the code will be unloaded if it is still
loaded and if the executable is of a type that supports unloading. If
you keep this in mind, and if you make sure that everything that uses
the bundle keeps a retain on the CFBundle object, then you can just use
the bundle naturally and never have to worry about when it is loaded and
unloaded.
On the other hand, if you want to manually manage when the bundle is loaded and unloaded, then you can use CFBundleLoadExecutable
and CFBundleUnloadExecutable
—although
this technique is not recommended. These functions force immediate
loading and unloading of the executable (if it has not already been
loaded/unloaded, and in the case of unloading if the executable is of a
type that supports unloading). If you do this, then the code calling CFBundleUnloadExecutable
is responsible for making sure that there are no remaining references
to anything in the bundle's code before it is unloaded. In the previous
approach, by contrast, this responsibility can be distributed to the
individual code sections that use the bundle, by making sure that each
one keeps its own retain on the CFBundle object.
One further point
about CFBundle reference counting: if you are taking the first
approach, but do not actually wish the bundle’s code to be unloaded (as
is often the case), or if you are taking the second approach of manually
managing the unloading yourself, then in many cases you do not actually
have to worry about releasing a CFBundle object. CFBundle instances are
uniqued, so there is only one CFBundle object for a given bundle, and
rarely are there so many bundles being considered at once that the
memory usage for CFBundle objects would be significant. There are cases
in which a process could create CFBundle objects for potentially an
unlimited number of bundles, and such processes would wish to balance
retains and releases carefully, but such cases are likely to be rare.
----------------------