On 15 May 2008, at 17:40, Johnny Lundy wrote:


but I am puzzled as to how my new class got instantiated. Here's what I did:

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.
4. Write an -init method that doesn't instantiate anything.
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.
6. Compile.
7. In IB, make an NSTextField and read in my class header file.
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.

Somehow, doing the above steps must have created an instance of my class, as one instance method can call another. I know that dragging out the NSObject made an instance, but my class does not know about it. 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?

I think you're confusing yourself (or others are), and you're tying yourself up in knots.

You placed the NSObject in the NIB, you gave it a class name of your class. What you're saying when you do that is "When this NIB is loaded, create an instance of my class". It's an NSObject you drag because NSObject is the super class of all other classes. i.e. your class is-a NSObject.

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."

You're right. [MyClass somemessage] sends a message to the "class object", not an instance of the class. For that to work you'd need to have +(void) somemessage; defined in MyClass. (Notice the '+' meaning class method, as opposed to '-' meaning instance method).

Class methods cannot access instance variables (ivars) because there is no instance associated with the call to contains the variables. (There might be hundreds of instances of a class in the system, which one contains the ivar I want to access) This is why you get the issues with +initalize() not being allowed to access ivars. It's a class method.

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.

This shouldn't be the case, and suggests you're not doing things quite right.

Make sure you are setting the class by editing the Class Identity field in the Identity inspector, rather than just changing the name.

I just tried to do this in a new project and succeeded. Here's what I did:

1. Started a Cocoa Application Project
2. With 'New File' I added a Objective-C Class called MyClass. I left it empty, except I gave it an init method.

- (id) init
{
    self = [super init];
    if (self != nil) {
        NSLog(@"Initialized MyClass");
    }
    return self;
}

3. Opened the NIB and dragged an NSObject into play. I then set the class of the Object to MyClass.
4. Added a second MyClass instance in exactly the same way.
5. Saved, build, run, and look at the console.

You'll see that two messages are present, as two instances were created. and init is "always" the first message sent to a new instance.


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

You're right, in this case the Files Owner is the shared NSApplication instance. That's not always true, because NIBs can be loaded by any class, but NSApplication is always the owner of the first NIB loaded.

People connect to file's owner to allow the owner to access the objects in the NIB. (I use connect rather than bind to avoid confusion. Bindings are something different in cocoa-speak)

A common practice is to connect an object to the delegate outlet of the NSApplication instance. This allows the NSApplication to send messages to your code a predetermined key times. For example, when the user selects quit from the menu, the object linked to the delegate outlet of the NSApplication will be sent a message to confirm if the application should terminate, by sending it the aptly named applicationShouldTerminate message. These messages are detailed in the NSApplication docs under delegate methods.

If that link wasn't made the NSApplication wouldn't know where to send the message. There are no magic connections made between objects instantiated by the NIB, and those that are instantiated some other way. File's Owner tends to be the gateway between these two worlds, with NIB objects being connected to outlets of File's Owner, or (less commonly) File's Owner being connected to outlets of NIB objects.

File's Owner is not one of my classes, and thus wouldn't know about any of my classes' properties to bind to. 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, it knows that objects connected to certain outlets are likely to respond to certain messages (like applicationShouldTerminate above). Your class might respond, it might not, it doesn't matter. What it does do is give you some points you can hook into and change the behaviour coded into NSApplication if you want to.
_______________________________________________

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