Skip navigation.
 
mlRe: Bypassing Interface Builder
FROM : Johnny Lundy
DATE : Thu May 15 18:40:32 2008

On May 15, 2008, at 5:26 AM, <email_removed> wrote:

> Message: 6
> Date: Thu, 15 May 2008 08:15:41 +0200
> From: Uli Kusterer <witness.of.<email_removed>>
> Subject: Re: Bypassing Interface Builder
> To: Johnny Lundy <<email_removed>>
> Cc: <email_removed>
> Message-ID: <<email_removed>>
> Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes
>
> Am 15.05.2008 um 02:15 schrieb Johnny Lundy:

>>

>  This may seem backwards, but since every NSObject implements
> setValue:forKey: already to look up the instance variable with the
> same name as the key and assign it the given value, this actually
> means that your instance variables will all be set up with pointers to
> the loaded objects by the time your awakeFromNib method is called.
> I.e. you don't have to write that huge function, you just drag from
> outlets to objects in IB while you're already dragging and clicking to
> create your GUI.
>
>  The object names, as far as I'm aware, are actually only there to
> help you navigate the objects in a NIB at design time.
>


OK - I really don't need the name then, 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?

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.

There needs to be an actual reference manual, one page per item on 
these checkboxes and popups, to explain them. I know the engineers who 
wrote the code behind them understand it, so it is not magic - and 
shouldn't require massive trial and error of every binding and every 
controller property to get something to work. These things are not 
difficult - they are just *not documented*.

Amazon shipped my copy of Aaron's Third Edition yesterday, so I'll be 
devouring that as soon as it arrives.


>> Say I drag out an object and set its class to MyClass. IB dutifully
>> names the object MyClass also. So in my code if I code [MyClass
>> somemessage], does that message go to the Class Object or to the
>> instance made in IB? If to the Class Object, how do I code to refer
>> to the instance?

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


>> Also, I found out that IB will not let me make 2 instances of the
>> same Class. In code, I could say myClassInstance1 = [MyClass new];
>> and MyClassInstance2 = [MyClass new];, but apparently not in IB.

>
>  You can make two instances of a class in the same NIB by dragging
> out two Objects from the palette and seting their custom class. But as
> you now know, the names are only for designing, and don't really have
> any use outside that.
>


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 has been a mystery to me for six years now.
>>
>> Also, the documentation only says about File's Owner that it is the
>> object that loaded the nib file. What is that object, if my nib file
>> just gets loaded at application launch?

>
>  Well, the MainMenu.nib, the main NIB file, gets loaded by the single
> NSApplication object in your application, so that's the File's Owner
> in that case. In other NIBs, the File's owner is generally the
> NSWindowController or NSViewController or NSDocument that loaded the
> corresponding NIB, or if you're using NSNibLoading directly, it's
> whatever object you passed in as the owner.
>


Right. I can understand that, that the owner is the shared application 
instance. But why do people bind nib objects to File's Owner? 
(Example: the Email and Mailboxes demo does this, and never explains 
what binding to File's Owner actually does - it, like many 
"tutorials", just says to do it. That teaches me nothing.) 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.

>

Related mailsAuthorDate
mlBypassing Interface Builder colo May 14, 16:36
mlRe: Bypassing Interface Builder I. Savant May 14, 17:11
mlRe: Bypassing Interface Builder colo May 14, 17:35
mlRe: Bypassing Interface Builder I. Savant May 14, 17:43
mlRe: Bypassing Interface Builder Andy Lee May 14, 17:50
mlRe: Bypassing Interface Builder colo May 14, 17:53
mlRe: Bypassing Interface Builder I. Savant May 14, 17:58
mlRe: Bypassing Interface Builder David Wilson May 14, 17:59
mlRe: Bypassing Interface Builder I. Savant May 14, 18:01
mlRe: Bypassing Interface Builder I. Savant May 14, 18:05
mlRe: Bypassing Interface Builder Gregory Weston May 14, 18:06
mlRe: Bypassing Interface Builder glenn andreas May 14, 18:13
mlRe: Bypassing Interface Builder Wayne Packard May 14, 18:26
mlRe: Bypassing Interface Builder Andy Lee May 14, 18:37
mlRe: Bypassing Interface Builder Stefan Werner May 14, 18:46
mlRe: Bypassing Interface Builder Bill Bumgarner May 14, 19:00
mlRe: Bypassing Interface Builder Boyd Collier May 14, 19:34
mlRe: Bypassing Interface Builder colo May 14, 19:37
mlRe: Bypassing Interface Builder Julius Guzy May 14, 22:05
mlRe: Bypassing Interface Builder Torsten Curdt May 14, 22:49
mlRe: Bypassing Interface Builder colo May 15, 00:53
mlRe: Bypassing Interface Builder Graham Cox May 15, 01:26
mlRe: Bypassing Interface Builder Graham Cox May 15, 01:41
mlRe: Bypassing Interface Builder colo May 15, 02:14
mlRe: Bypassing Interface Builder Johnny Lundy May 15, 02:15
mlRe: Bypassing Interface Builder Graham Cox May 15, 02:29
mlRe: Bypassing Interface Builder I. Savant May 15, 02:43
mlRe: Bypassing Interface Builder Graham Cox May 15, 02:45
mlRe: Bypassing Interface Builder I. Savant May 15, 02:51
mlRe: Bypassing Interface Builder I. Savant May 15, 02:54
mlRe: Bypassing Interface Builder Andy Lee May 15, 03:02
mlRe: Bypassing Interface Builder Graham Cox May 15, 03:02
mlRe: Bypassing Interface Builder Andy Lee May 15, 03:06
mlRe: Bypassing Interface Builder I. Savant May 15, 03:07
mlRe: Bypassing Interface Builder Andy Lee May 15, 03:08
mlRe: Bypassing Interface Builder I. Savant May 15, 03:09
mlRe: Bypassing Interface Builder I. Savant May 15, 03:15
mlRe: Bypassing Interface Builder Andy Lee May 15, 03:29
mlRe: Bypassing Interface Builder Julius Guzy May 15, 03:35
mlRe: Bypassing Interface Builder I. Savant May 15, 03:37
mlRe: Bypassing Interface Builder Johnny Lundy May 15, 04:33
mlRe: Bypassing Interface Builder Julius Guzy May 15, 04:36
mlRe: Bypassing Interface Builder Johnny Lundy May 15, 04:54
mlRe: Bypassing Interface Builder Graham Cox May 15, 05:43
mlRe: Bypassing Interface Builder Uli Kusterer May 15, 07:50
mlRe: Bypassing Interface Builder Uli Kusterer May 15, 07:55
mlRe: Bypassing Interface Builder Uli Kusterer May 15, 08:15
mlcocoa mentoring (was Re: Bypassing Interface Builder) Torsten Curdt May 15, 15:36
mlRe: cocoa mentoring (was Re: Bypassing Interface Builder) Paul Bruneau May 15, 15:47
mlRe: cocoa mentoring (was Re: Bypassing Interface Builder) Uli Kusterer May 15, 16:08
mlcocoaheads frankfurt (was Re: cocoa mentoring) Torsten Curdt May 15, 16:44
mlRe: cocoa mentoring (was Re: Bypassing Interface Builder) Torsten Curdt May 15, 16:51
mlRe: Bypassing Interface Builder Andy Lee May 15, 17:11
mlRe: Bypassing Interface Builder Johnny Lundy May 15, 18:40
mlRe: cocoa mentoring (was Re: Bypassing Interface Builder) Dennis Munsie May 15, 19:34
mlRe: Bypassing Interface Builder Paul Sargent May 15, 20:07
mlRe: Bypassing Interface Builder Uli Kusterer May 15, 20:48
mlRe: Bypassing Interface Builder Shawn Erickson May 15, 22:20
mlRe: Bypassing Interface Builder Shawn Erickson May 15, 22:30
mlRe: Bypassing Interface Builder Johnny Lundy May 15, 22:32
mlRe: cocoa mentoring (was Re: Bypassing Interface Builder) Torsten Curdt May 15, 23:03