Re: Hiding superclass methods
Re: Hiding superclass methods
- Subject: Re: Hiding superclass methods
- From: email@hidden
- Date: Fri, 10 May 2002 13:33:45 -0700
Brock Brandenberg wrote:
|I think we've run into another area in the Apple docs that isn't
|clarified very well. I feel like the reference you mentioned:
|
|/Developer/Documentation/Cocoa/TasksAndConcepts/ProgrammingTopics/LoadingResources/
|Concepts/NibFileLoaded.html
|
|... paints too broad of a stroke with its wording.
I won't argue with you there. On the other hand, the particular line I quoted (which appears below, for readers new to this exchange) is very clear and specific. The question is, is it correct?
|I think what's confusing is that opening, loading and initialization
|constitute a multi-step process and we may be interpreting some of the
|wording in the docs too broadly. Bill Cheeseman will probably say that
|the documentation is exactly correct (I've seen him point this out
|before :), but it doesn't have enough detail or enough examples to put
|it all in perspective. Once you know how it all works, the docs may be
|perfectly clear. Hindsight's always 20-20.
It's not so much hindsight as, what does the author assume the reader already knows? You can't assume he knows nothing, or every document turns into a tutorial. Apple seems to assume that the reader is reasonably versed in the general structure of things, and wants the details. (Pity they don't always *include* those details.) There's also the problem of having experts write the documentation: the expert has been doing things so long that some things are just "obvious", and therefore don't need to be said. (I'm not defending Apple here, just trying to make clear why some of these lapses occur. Part of a tech writer's job is to check for just that kind of thing.)
Once you've gained enough expertise, the gaping holes no longer appear so gaping, simply because now you know what the author assumed you knew; the things the author thought obvious are now obvious to you, too.
Too, it matters little if the documentation is "exactly correct" but still leaves out what you really want to know. Answering "Yes" to "can I engage the framistan when in kibitzer mode?" may be technically correct, but doesn't tell you anything useful, either.
|Now, I have to make sure that I don't step out of my bounds of
|understanding here because I haven't loaded any nib files using the
|NSBundle methods. I've only loaded ones from a custom window controller
|using initWithWindowNibName: to load the nib and windowDidLoad: to start
|using the window after loading.
Then you *have* loaded nib files using NSBundle, because NSWindowController uses the NSBundle methods. (So far as I know, without wandering off into Carbonland, NSBundle is the only game in town.)
|In the reference, Apple says:
|
|"If you need to initialize an object after its nib file has been loaded,
|create an awakeFromNib method for the object. It's called after all nib
|file's objects have been loaded and all the connections have been set
|up."
|
|This statement is correct, but it leaves something out. When the file is
|loaded, the designated initializers must be called for the objects
|otherwise the objects couldn't be instantiated.
Not true. The object can be instantiated (or, properly, *re*-instantiated) from an archived copy stored in the nib file. The documents state (just where, I can't say at the moment) that this is what's done: Interface Builder initializes the object by setting things directly and archives the object; your program, using NSBundle, then "dearchives" it. Essentially, the nib file contains "freeze-dried" objects; NSBundle adds the metaphorical water when it loads the nib file.
(More generally--or more pedantically, depending on your leanings--the "key-value coding" mechanism is capable of tracking down instance variables and changing them, even if they're private to the class.)
|However, like it says, you can't fully initialize your custom objects
|until awakeFromNib: is called because no IBOutlets are valid until
|this time. But the reference goes on to say:
|
|"Note that the init and initWithFrame: methods are never called when a
|nib file is opened. As you create a nib file, Interface Builder
|automatically initializes its elements. When you later load that nib
|file, all its elements are already initialized."
|
|I think this is where my confusion starts, and the critical word here is
|"opened." I don't know the exact chronology, but I would suspect that
|"opening" only brings the serial stream of data into memory, but does
|not instantiate any of what it represents. "Loading" is what decodes and
|instantiates any objects. Am I correct?
Only an Apple person, with access to the source code, could say for sure. However, as "opening" (as you define it here) and "loading" a nib file are pretty much inseparable actions from the programmer's viewpoint, I expect they mean "open" to include the loading process, and are using "opened" and "loaded" interchangably. You're correct, though, in saying that they should be more precise here. But, again, the statement "all its elements are already initialized" is a pretty clear statement; if the objects are already initialized, there's no need to call the initializer methods.
|Now, I know that any custom subclasses that I instantiate by placing
|them in a window's content view (in my main nib file) get their
|initWithFrame: method called when that nib file is "loaded".
Do you know this as fact, from direct experience, or is it simply "how can they *not* be called?" I've included NSLog calls in initWithFrame: in views I've loaded from a nib file, and the calls were not executed, indicating that initWithFrame: wasn't executed, either.
|I feel like this is an absolutely necessary part of the initialization
|process since Cocoa can't just ignore initializers. An object has to
|have an initializer called.
Not true. Cocoa has ways of "initializing" an object without invoking an initializer (the "key-value coding" I mentioned earlier). As well, Interface Builder, being written by Apple, can take advantage of knowledge of the inner workings of Cocoa to do things that mere mortal programmers can't do.
|...
|
|I'd love to know what kind of experimentation you've done that doesn't
|call the init methods because I don't want to ever get caught by this. I
|feel like I had a grasp on the order of initialization, and now there's
|a cloud over my head :)
The question isn't so much order of initialization as, how are *archived* objects restored to full object status? The objects from a nib file are truly *loaded*--*re*created, not allocated--from copies which have been previously initialized (even if by underhanded means) by Interface Builder and saved in the nib file. Since they're not new objects as far as Cocoa is concerned, the initialization methods aren't called.
|Chronologies of events is one of those areas that I gripe about in the
|Apple documentation.
Generally, I've found that order-of-execution information is there, although it's often better hidden than it ought to be. It certainly isn't laid out in a neat tabular form, and that would be helpful, for sure, but the information does seem to be there. Often, it's part of the list of messages sent to delegate objects.
Do keep asking questions. Keep asking until everything makes sense, even if the questions appear "dumb". That's how you learn. In addition, that's the only way we'll sort out whether the documentation is outright wrong, or merely incomplete. The best test of documentation is seeing what questions people still need answered after reading them.
Glen Fisher
_______________________________________________
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.