Re: [SOLVED] NSBundle won't release ? [by NOT using NSBundle]
Re: [SOLVED] NSBundle won't release ? [by NOT using NSBundle]
- Subject: Re: [SOLVED] NSBundle won't release ? [by NOT using NSBundle]
- From: Gen Kiyooka <email@hidden>
- Date: Mon, 18 Apr 2005 21:48:06 -0700
I did some tests on the various dynamic linking mechanisms in OSX awhile back. It is true that some of
the dynamic lib mechanisms do not unload even when their reference count is zero.
My tests were done with straight bsd-style code, no cocoa or carbon. My goal was to ascertain
the circumstances under which C++ static destructors would be called.
However, in my tests, Bundle packages unload with the same semantics as Windows DLLs, which is
to say, as you would expect. Both Frameworks and dylibs unload when the application terminates.
The way I ran my tests were to hook into the mach load/unload entry points (callbacks made by the OS
into your DLL at termination) and write some printf strings to the console:
As you can see, both the Framework (private framework) and the dylib sent their mach-o termination
events after the application exit, rather than after being unloaded. Only the bundle unloaded at the right
time.
So if your bundle isn't getting unloaded, I'm guessing the ref-count is still high enough to keep it in memory.
FIRST RUN -------------------------------------------------------------
locationURL <CFURL 0x505130 [0xa01900e0]>{type = 15, string = Contents/Frameworks/,
base = <CFURL 0x501d60 [0xa01900e0]>{type = 15, string = file://localhost/Code/Test.Apps/LoadDLL/LoadDLL.app/, base = (null)}}
LoadFromURL: <CFURL 0x505860 [0xa01900e0]>{type = 15, string = Contents/Frameworks/MyFramework.framework,
base = <CFURL 0x501d60 [0xa01900e0]>{type = 15, string = file://localhost/Code/Test.Apps/LoadDLL/LoadDLL.app/, base = (null)}}
MyFramework.framework::SimpleClass::SimpleClass (C++ static construction)
MyFramework.framework::module_load() mach-o dyld event
MyFramework.framework::module_bind() mach-o dyld event
MyFramework.framework::Construct()
LoadDLL::Calling SayHello()
MyFramework.framework::SayHello() !HELLO! deadffff Hellooooooo!
LoadDLL::Post dead00ee=SayHello()
MyFramework.framework::Destruct()
LoadDLL - after unloading DLL
................................................................................................................................
locationURL <CFURL 0x505850 [0xa01900e0]>{type = 15, string = Contents/Resources/,
base = <CFURL 0x501d60 [0xa01900e0]>{type = 15, string = file://localhost/Code/Test.Apps/LoadDLL/LoadDLL.app/, base = (null)}}
LoadFromURL: <CFURL 0x505630 [0xa01900e0]>{type = 15, string = Contents/Resources/MyBundle.bundle,
base = <CFURL 0x501d60 [0xa01900e0]>{type = 15, string = file://localhost/Code/Test.Apps/LoadDLL/LoadDLL.app/, base = (null)}}
MyBundle.bundle::SimpleClass::SimpleClass (C++ static construction)
MyBundle.bundle::module_load() mach-o dyld event
MyBundle.bundle::module_bind() mach-o dyld event
MyBundle.bundle::Construct()
LoadDLL::Calling SayHello()
MyBundle.bundle::SayHello() !HELLO! deadffff Hellooooooo!
LoadDLL::Post dead00ee=SayHello()
MyBundle.bundle::Destruct()
MyBundle.bundle::module_term() mach-o dyld event
MyBundle.bundle::__destroy_global_chain START
MyBundle.bundle::SimpleClass::~SimpleClass (C++ static destruction time)
MyBundle.bundle::__destroy_global_chain END
MyBundle.bundle::module_unload() mach-o dyld event
LoadDLL - after unloading DLL
................................................................................................................................
executableURL <CFURL 0x505480 [0xa01900e0]>{type = 0, string = /Code/Test.Apps/LoadDLL/LoadDLL.app/Contents/MacOS/LoadDLL, base = (null)}
locationURL <CFURL 0x505630 [0xa01900e0]>{type = 0, string = /Code/Test.Apps/LoadDLL/LoadDLL.app/Contents/MacOS/, base = (null)}
CFBaseDLL::PathFromURL /Code/Test.Apps/LoadDLL/LoadDLL.app/Contents/MacOS/MyDylib.dylib
LoadFromURL: <CFURL 0x505480 [0xa01900e0]>{type = 0, string = /Code/Test.Apps/LoadDLL/LoadDLL.app/Contents/MacOS/MyDylib.dylib, base = (null)}
MyDylib.dylib::SimpleClass::SimpleClass (C++ static construction)
MyDylib.dylib::module_load() mach-o dyld event
MyDylib.dylib::module_bind() mach-o dyld event
MyDylib.dylib::Construct()
000bf000 = ::NSAddImage(/Code/Test.Apps/LoadDLL/LoadDLL.app/Contents/MacOS/MyDylib.dylib,options)LoadDLL::Calling SayHello()
MyDylib.dylib::SayHello() !HELLO! deadffff Hellooooooo!
LoadDLL::Post dead00ee=SayHello()
MyDylib.dylib::Destruct()
I_NSImageDLL::map_NSModule_to_usage_count::UnlinkAll()
Unlinking: 00303bef reference_count: 3
LoadDLL - after unloading DLL
................................................................................................................................
SECOND RUN -------------------------------------------------------------
locationURL <CFURL 0x505480 [0xa01900e0]>{type = 15, string = Contents/Frameworks/,
base = <CFURL 0x501d60 [0xa01900e0]>{type = 15, string = file://localhost/Code/Test.Apps/LoadDLL/LoadDLL.app/, base = (null)}}
LoadFromURL: <CFURL 0x5054d0 [0xa01900e0]>{type = 15, string = Contents/Frameworks/MyFramework.framework,
base = <CFURL 0x501d60 [0xa01900e0]>{type = 15, string = file://localhost/Code/Test.Apps/LoadDLL/LoadDLL.app/, base = (null)}}
MyFramework.framework::Construct()
LoadDLL::Calling SayHello()
MyFramework.framework::SayHello() !HELLO! deadffff Hellooooooo!
LoadDLL::Post dead00ee=SayHello()
MyFramework.framework::Destruct()
LoadDLL - after unloading DLL
................................................................................................................................
locationURL <CFURL 0x502330 [0xa01900e0]>{type = 15, string = Contents/Resources/,
base = <CFURL 0x501d60 [0xa01900e0]>{type = 15, string = file://localhost/Code/Test.Apps/LoadDLL/LoadDLL.app/, base = (null)}}
LoadFromURL: <CFURL 0x505730 [0xa01900e0]>{type = 15, string = Contents/Resources/MyBundle.bundle,
base = <CFURL 0x501d60 [0xa01900e0]>{type = 15, string = file://localhost/Code/Test.Apps/LoadDLL/LoadDLL.app/, base = (null)}}
MyBundle.bundle::SimpleClass::SimpleClass (C++ static construction)
MyBundle.bundle::module_load() mach-o dyld event
MyBundle.bundle::module_bind() mach-o dyld event
MyBundle.bundle::Construct()
LoadDLL::Calling SayHello()
MyBundle.bundle::SayHello() !HELLO! deadffff Hellooooooo!
LoadDLL::Post dead00ee=SayHello()
MyBundle.bundle::Destruct()
MyBundle.bundle::module_term() mach-o dyld event
MyBundle.bundle::__destroy_global_chain START
MyBundle.bundle::SimpleClass::~SimpleClass (C++ static destruction time)
MyBundle.bundle::__destroy_global_chain END
MyBundle.bundle::module_unload() mach-o dyld event
LoadDLL - after unloading DLL
................................................................................................................................
executableURL <CFURL 0x505480 [0xa01900e0]>{type = 0, string = /Code/Test.Apps/LoadDLL/LoadDLL.app/Contents/MacOS/LoadDLL, base = (null)}
locationURL <CFURL 0x505560 [0xa01900e0]>{type = 0, string = /Code/Test.Apps/LoadDLL/LoadDLL.app/Contents/MacOS/, base = (null)}
CFBaseDLL::PathFromURL /Code/Test.Apps/LoadDLL/LoadDLL.app/Contents/MacOS/MyDylib.dylib
LoadFromURL: <CFURL 0x505480 [0xa01900e0]>{type = 0, string = /Code/Test.Apps/LoadDLL/LoadDLL.app/Contents/MacOS/MyDylib.dylib, base = (null)}
MyDylib.dylib::Construct()
000bf000 = ::NSAddImage(/Code/Test.Apps/LoadDLL/LoadDLL.app/Contents/MacOS/MyDylib.dylib,options)LoadDLL::Calling SayHello()
MyDylib.dylib::SayHello() !HELLO! deadffff Hellooooooo!
LoadDLL::Post dead00ee=SayHello()
MyDylib.dylib::Destruct()
I_NSImageDLL::map_NSModule_to_usage_count::UnlinkAll()
Unlinking: 00303bef reference_count: 3
LoadDLL - after unloading DLL
................................................................................................................................
END END END -------------------------------------------------------------
MyFramework.framework::module_term() mach-o dyld event
MyFramework.framework::__destroy_global_chain START
MyFramework.framework::SimpleClass::~SimpleClass (C++ static destruction time)
MyFramework.framework::__destroy_global_chain END
MyFramework.framework::module_term() mach-o dyld event
MyFramework.framework::__destroy_global_chain START
MyFramework.framework::__destroy_global_chain END
MyFramework.framework::module_unload() mach-o dyld event
MyDylib.dylib::module_term() mach-o dyld event
MyDylib.dylib::__destroy_global_chain START
MyDylib.dylib::SimpleClass::~SimpleClass (C++ static destruction time)
MyDylib.dylib::__destroy_global_chain END
MyDylib.dylib::module_term() mach-o dyld event
MyDylib.dylib::__destroy_global_chain START
MyDylib.dylib::__destroy_global_chain END
MyDylib.dylib::module_unload() mach-o dyld event
On Apr 18, 2005, at 2:36 PM, Dirk van Oosterbosch wrote:
FYI
On second thoughts,
I guess it is not that strange behavior of NSBundle to not want to release, since you also cannot unload code that is loaded with a bundle. (And using bundles as a document format is not exactly what it's build for, I presume).
But what are my alternatives?
Well, NOT use a NSBundle, I decided.
I figured out in the end I only used its -objectForInfoDictionaryKey to get to its Info.plist. So I now I am just loading the xml Info.plist from file and putting its contents in a NSDictionary. Job done.
dirk
On 18-apr-05, at 15:28, Dirk van Oosterbosch wrote:
Hi all,
I am witnessing a strange behavior with the (not) release of NSBundle. It seems it doesn't want to be released, period. No matter how many -release(s) you send it.
I am using
setBundle:[NSBundle bundleWithPath:bundlePath]];
and the accessor method
- (void)setBundle:(NSBundle *)aBundle
{
[aBundle retain];
[bundle release];
bundle = aBundle;
}
But the [self setBundle:nil]; from my -dealloc doesn't actually release it.
I am using this NSBundle as my document base type (meaning my NSDocument-subclass owns a MyOwnBundle instance -from which the code above stems- which owns a NSBundle). But everytime I open / close / open / cl... the same document, I am seeing the first state of that document, regardless of whether I changed it behind the applications back. I am NSLogging the bundle's -retaincount and every time I set the bundle using the above +bundleWithPath method, and using the same bundlePath, I see my retain count explode: 8, 32, 128, 384, 640, 896, 1152. This can't be right.
in this old thread http://www.cocoabuilder.com/archive/message/cocoa/2001/11/24/43545 Ondra Cada says "rather, unless you really need to do that, don't retain the result of bundleWithPath"
Well, I guess I am. But what are my alternatives?
Are there other things I should do to get the bundle? Or are there alternatives to releasing it?
Thanks,
Dirk van Oosterbosch
-----------------------------
Dirk van Oosterbosch
de Wittenstraat 225
1052 AT Amsterdam
the Netherlands
T ++ 31 20 7765565
M ++ 31 6 48401910
W http://labs.ixopusada.com
----------------------------- _______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden _______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden