Re: Bypassing Interface Builder
Re: Bypassing Interface Builder
- Subject: Re: Bypassing Interface Builder
- From: Paul Sargent <email@hidden>
- Date: Thu, 15 May 2008 19:07:08 +0100
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 (email@hidden)
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:
This email sent to email@hidden