Am 15.05.2008 um 18:40 schrieb Johnny Lundy:
1. Create the class, the .h and .m files.
2. Code the ivars, their @property directives, and their @synthesize directives.

3. Write 2 instance methods plus the -init method. There are no class methods, and no IBOutlets.


 Just like you'd do without NIBs, yes.

4. Write an -init method that doesn't instantiate anything.

Well, init gets called when your object is instantiated, it doesn't instantiate the object itself. Of course, init can instantiate *other* objects that your object needs, like an NSTextField would probably instantiate an NSMutableString object to hold whatever text it's supposed to display.

5. There is no +initialize method, as I don't understand it. When I have tried to use it, it complains I can't refer to ivars.

+initialize is a class method, hence the "+". It is kind of a constructor for the class (as opposed to the -init methods that get called on objects. This was one of the harder parts in Objective C, to teach oneself to read + to mean "class method" and - to mean "object/ instance method".

6. Compile.
7. In IB, make an NSTextField and read in my class header file.

Not related, and as others have said, IB3 reads your classes automagically as soon as you save them.

8. In IB, drag out an NSObject and give it the class name of my new class. I did NOT control-drag anything to anything, and there are no IBOutlets in my code.

If that is all you did, then an object of your class was never instantiated. The only thing you got was an NSObject. The least you'll have to do is go to the "identity" pane of the inspector for this instance and type the name of your class into the "custom class" field.

Somehow, doing the above steps must have created an instance of my class, as one instance method can call another.

What do you mean by 'one instance method can call another' ? Who is calling whom, how? If you just created this object, and nobody else has an outlet pointing to it, then while it was instantiated, nobody can call a method on it, because nobody has a pointer to it. Someone needs to have an outlet or a binding to it to call a method on it (or if your object has an action, then it'll probably pass a pointer to itself as the sender of that action, so whoever is the target could send a message back then, etc. etc.)

I know that dragging out the NSObject made an instance, but my class does not know about it.

What? How? Who? I'm not following you here. When you drag an NSObject from the palette, you essentially tell IB to call alloc and init on that icon's "custom class" (or on a generic NSObject if you don't specify a custom class). That is how your object gets instantiated: NSNibLoading calls alloc to get a block of memory the size of your object, and your init method then sets that block of memory up in the appropriate way.

So how come the instance methods in my class work? How can the property that I bound to an NSTextField work if there is no instance of my class to hold the property?

Well, the object you drag out is the instance. Though if it's just an NSObject, you'll probably find your console full of error messages that the binding to that property can't be established, because NSObject doesn't have these properties.

Strangely enough, the "hard" APIs like NSURLConnection were easy for me, and worked the first time, because the documentation was extensive and said exactly what the API parameters were for. Not so for trivially simple things like instantiating an object, or even worse, explaining what all the myriad of popups and checkboxes in an IB Bindings pane do. The tool tips are a complete joke - all they do is repeat the label of the item.

Actually, they've been very helpful to me today. But it depends on what tool tips you look at.

And don't feel disheartened: Bindings, as the documentation states, are an advanced topic. It's OK if you start out with properties, connections and target/action, and write the rest of the code yourself for now. Once you feel familiar with that, go back to bindings. Once you are intimately familiar with what manual work is involved in a Cocoa application, you'll realize how bindings can save you work there because they replace this or that piece of code you had to hand-write before. You'll essentially know what bindings do under the hood.

That object goes to the instance. You dragged out an *object*, an
instance, so that's what you get. I expected that, myself, so never
got confused by the name being the class name, but I can see how one
could be.

But [MyClass somemessage] tries to message the class, and I get a "Class MyClass may not respond to somemessage", which makes sense since there is no class method "somemessage."

Yes, if you specify the class name as the target, then the message will go to the class. If you want to message an actual instance, i.e. an object, you need a pointer to that object. Whether you name your object "MyClass" or "George" in the NIB doesn't matter, you still won't be able to call it as [Peter somemessage]. What you need to do instead is add an outlet to whatever object is sending this message, and control-drag to make IB aware that you want this outlet to point at that particular instance.

It won't let me set the class for the second Object. I can type it in, but on hitting Tab or Return or clicking out of the field, the text I entered disappears and it gets replaced with a dimmed "NSObject." I thought it was a glitch in IB, but I discovered that it only does that if you try and set more than one IB object to the same class.


Setting the *name* does not set the *class*. As I said, the name is *completely ignored*, it is simply for you when you're using IB so you can more easily tell the two blue boxes apart. To change the class, type it into the "custom class" field on the "identity" pane of the inspector.

Right. I can understand that, that the owner is the shared application instance. But why do people bind nib objects to File's Owner?

Well, in the case of the application object you generally don't do that. But in the case of an NSDocument-based application or an NSWindowController subclass, both of which load their own NIBs, the file's owner is the instance of your NSDocument or NSWindowController subclass (or whatever), which loaded the NIB when you created an instance of that subclass.

Since creating that NSWindowController was what caused the NIB to be loaded, the window controller isn't a regular object in the NIB, it is the owner of that NIB. If you dragged an NSWindowController into the NIB, you'd get a second NSWindowController instance. That's not what you want. That's where File's Owner comes in: It is a placeholder for the object that loaded this NIB so you can bind to it, connect to it, point outlets at it etc.

Does that clarify things a bit? I'm not quite sure how I can phrase this differently.

File's Owner is not one of my classes,

File's Owner is *not* a class. It is simply a name (remember, names are mostly ignored) for an instance. For the instance that asked NSNibLoading to instantiate the objects in this NIB for it.

and thus wouldn't know about any of my classes' properties to bind to.

Look at the "custom class" of the File's Owner. In general, for a main NIB that will be type NSApplication, while for an NSDocument's NIB it will be MyDocument or whatever name you gave it when you created it. If you create your own NIB without using any of the existing templates, you may have to set that object's custom class to be that of the object that loads the NIB.

Does the NSApp shared application instance (represented by File's Owner) somehow know about all properties of all objects in all of my classes? That would be great if it does, I have just never seen it written.

 No.



Cheers,
-- Uli Kusterer
"The Witnesses of TeachText are everywhere..."
http://www.zathras.de





_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Reply via email to