Re: loadNibNamed:owner: Who disposes of the loaded objects?
Re: loadNibNamed:owner: Who disposes of the loaded objects?
- Subject: Re: loadNibNamed:owner: Who disposes of the loaded objects?
- From: James DiPalma <email@hidden>
- Date: Fri, 26 Sep 2003 19:00:40 -0700
>
If I want to provide the same behavior as NSWindowController in my
>
app, how do I determine what objects are in my NIB file? Currently,
>
all objects are in an NSView resp. an NSPanel, but later there may be
>
other objects in there, and I'd like to avoid leaking anything.
One recommendation for how to implement this functionality:
@interface NSBundle (JimNibLoading)
+ (NSArray*) topLevelObjectsFromLoadingNibNamed:(NSString*)name
owner:(id)owner;
+ (NSArray*) topLevelObjectsFromLoadingNibFile:(NSString*)file
owner:(id)owner;
@end
I've included some implementation below. By returning an array of
top-level objects, loading nib files would comply with retain-release
rules (since this array is autoreleased and all objects within it will
also get autoreleased if this array goes away). Your code would use
these methods to load a nib and retain its returned array until you
want your top-level objects to go away.
I would be happy to see AppKit do something like these methods so nib
loading obeyed retain-release rules.
>
When you load a nib file, all its top level objects have a reference
>
count
>
of one. When the objects are no longer needed, another object needs to
>
release them. That other object is usually the file9s owner.
All its top-level objects do not actually have a retain count (why this
doc uses reference count, I don't know) of one. They actually have a
retain count of +1. Which may not be relevant, but many objects will be
retained when they are connected to other objects and this statement
may be misleading to someone reading it. One object that actually does
obey this documentation (which is a bug) is NSFontManager. Two objects
that might be thought of as top-level objects that do not get retained
because of nib loading are a nib-file's owner and its first responder
(which is represented as nil anyway).
Usually file's owner? I think that other object should actually be
whoever loaded that nib file. For example in a default ProjectBuilder
"Cocoa Document based application", a window controller will load your
document nib, but it is not file's owner and it is responsible for
releasing top-level objects.
-jim
@implementation NSBundle (JimNibLoading)
+ (NSArray*) topLevelObjectsFromLoadingNibNamed:(NSString*)name
owner:(id)owner
{
NSBundle * bundle;
NSString * file;
file = nil;
bundle = [NSBundle bundleForClass:[owner class]];
if (nil != bundle) {
file = [bundle pathForResource:name ofType:@"nib"];
}
// Documentation for loadNibNamed states that NSBundle only
searches for nib name in mainBundle if there is no bundle for owner's
class. Search in mainBundle anyway?
if (nil == file) {
bundle = [NSBundle mainBundle];
file = [bundle pathForResource:name ofType:@"nib"];
}
// WARNING what does loadNibNamed: do if a nib file does not exist?
May06-2003
return [NSBundle topLevelObjectsFromLoadingNibFile:file
owner:owner];
}
+ (NSArray*) topLevelObjectsFromLoadingNibFile:(NSString*)file
owner:(id)owner
{
NSDictionary * nameTable;
NSMutableArray * topLevelObjects;
topLevelObjects = [NSMutableArray array];
nameTable = [NSDictionary
dictionaryWithObjectsAndKeys:topLevelObjects, @"NSTopLevelObjects",
owner, @"NSOwner", nil];
if ([NSBundle loadNibFile:file externalNameTable:nameTable
withZone:[owner zone]]) {
// nibInstantiateWithOwner retains each top level object
[topLevelObjects makeObjectsPerformSelector:@selector(release)];
return topLevelObjects;
}
return nil;
}
@end
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.