PDA

View Full Version : what could be causing the IBOutlet id to be nil?




Chirone
Mar 5, 2009, 09:44 PM
Hi there,

i have a whole lot of NIB objects and they are all have their Referencing Outlets going to somewhere.

when i run the program the program crashes on start up because the IBOutlet id objects appear to be nil
at least that's what i gather from the error message that's being printed out (and it only prints out something if i print out something that totally unrelated to the error message)

here's the stupid thing though...
in ClassA if i point the reference outlet of say a slider to an IBOutlet id the program runs fine and everything works
in ClassB if i point the reference outlet of the SAME slider to the IBOutlet id (and remove the old reference outlet) the program crashes as soon as it tries to access that object

it doesn't make any sense, because the NIB Objects respond to the IBAction methods quite nicely... they just don't respond to the IBOutlet ids...

what am i missing in ClassB so that all the objects of type IBOutlet id aren't nil?



eddietr
Mar 5, 2009, 10:02 PM
The way you are describing these things is probably not the way I would describe them. So it's a little hard to follow.

Maybe it would be better if you posted the actual errors you're seeing and more concrete information about which outlets specifically are not being set as you expected.

Chirone
Mar 6, 2009, 10:10 PM
hi, sorry for the bad explanation

i'll try again, i don't have access to the mac for the weekend so i can't paste the errors

in Interface Builder i have a set of sliders, text boxes, and buttons. they all have their reference outlet pointing to ClassA

in ClassA these reference outlets are not nil, and i can use them fine. it extends NSResponder and overrides the awakeFromNib method.

Because ClassA was getting very huge and it makes more sense to put some of those NIB objects in a different class that's what I did

so part of ClassA became ClassB
ClassB has an IBOutlet id for each relevant NIB object and each IBAction that those NIB objects are meant to trigger.

Now that there exists ClassB, ClassA makes an instance of ClassB so it can gain access to the IBOutlet id objects, because it needs to add a few of those to a dictionary so they can be access by some other class that has the dictionary.

When the program runs it makes the instance of ClassB but it claims that all the IBOutlet id objects are nil.
basically i know this because in ClassB's init method i told it to go

if(thisOutletID == nil) {
printf("broken\n");
}

and broken gets printed out twice (why twice? the init method is only called once)
however, this shouldn't be the case since in the Interface Builder the NIB objects were correctly linked to the correct IBOutlet id in ClassB

What am i doing wrong? why does ClassB not realise that the IBOutlet id objects do exist as it should do?
ClassB is no different to ClassA yet the NIB Objects only exist when they are pointing to an IBOutlet id object in ClassA...

eddietr
Mar 6, 2009, 11:13 PM
OK, so the first thing to remember about IB is that you are not connecting classes, you are connecting instances (or objects). So that's a key thing to understand.

So let's say you have an instance of "ClassB" in our nib, and you connect its outlets to various other objects. Then in your code you create a different instance of ClassB (which it sounds like you are doing), then your new instance will definitely not have any of the configuration of the first instance from the nib.

Again, the key point is that in IB you are not configuring classes, you are configuring (and saving) actual instances. Once you understand that, I think you'll understand exactly what's wrong.

Chirone
Mar 7, 2009, 12:32 AM
i thought as much

is there any way i can pass the IBOutlet id objects to other classes then?

ClassA requires the stuff in ClassB, is this possible?

eddietr
Mar 7, 2009, 12:45 AM
i thought as much

is there any way i can pass the IBOutlet id objects to other classes then?

ClassA requires the stuff in ClassB, is this possible?

Again, you want to make sure you understand the difference between a class and an object (instance). From the way you are describing it, you seem to be mixing up the two terms. And if you're just learning this stuff, mixing up the terms can cause you a lot of problems and frustration.

But let's say in your nib you have an object (we'll call it Object 1) that is of class (type) A. Then you have another object (we'll call it Object 2) that is of class (type) B.

Then Object 1 could have an outlet of type . And that outlet could be set in your nib to Object 2. Then Object 2 could, in turn, have other outlets set to other objects in the nib. Say, for example, Object 2 had an outlet of type [UIButton*] set to an [B]object called Button1.

Then Object1 could reference Button1 via Object2. That is definitely possible. For example the UIButton* outlet in Object2 could be a property called "firstButton", in which case Object1 could reference that button via Object2.firstButton

Hope that helps.

Chirone
Mar 7, 2009, 10:05 PM
uhh... not sure if i totally get it, let's see (i would try this now, but i dont have access to a mac yet)

ClassA header looks like this:


@interface ClassA {
ClassB* instanceOfClassB;
IBOutlet id *someSliderFromIB;
}
-(void) awakeFromNib;
-(IBAction) doSomething: (id)sender;

and ClassB header looks liket his:

@interface ClassB {
IBOutlet id *someTextFieldFromIB;
}
-(IBOutlet id*) getSomeTextFieldFromIB;
-(IBAction) doSomethingYo: (id)sender;


then in the implementation file of ClassA i can do this?

-(void) awakeFromNib {
instanceOfClassB = [[ClassB alloc] init];
NSMutableDictionary* pDict = [[NSMutableDictionary alloc] init];
[pDict object: [instanceOfClassB getSomeTextFieldFromIB] forKey: "hello"];
}

and that would add the text field from IB to the dictionary without generating errors? (i can't remember how to insert stuff into a dictionary off the top of my head, but you get the idea of what i'm after)

or would it be better to make the IBOutlet id a static object?

static IBOutlet id someTextFieldFromIB;
@interface ClassB {
...
}
...
+(IBOutlet id) getSomeTextFieldFromIB;

since declaring things as static means all instances of ClassB will refer to the same IBOutlet id
(i assume Obj C works that way with static variables)

eddietr
Mar 7, 2009, 10:59 PM
So let's start with this:



-(void) awakeFromNib {
instanceOfClassB = [[ClassB alloc] init];
NSMutableDictionary* pDict = [[NSMutableDictionary alloc] init];
[pDict object: [instanceOfClassB getSomeTextFieldFromIB] forKey: "hello"];
}



The key thing to understand is that in this code "instanceOfClassB" is a new instance of Class B. It is not the instance that already exists in the nib.

On the other hand, if you connect (in IB) your ClassB* outlet in your instanceOfClassA to the actual instance of ClassB in your nib, then you will have what you want.

There are some other issues in your post, like what an "id" is, but I think we can cover those later after you get this point. And also, I don't know if this whole approach is the right design for your app or not. But assuming you want to have these two classes and this relationship between the objects, I'm just trying to help you achieve that objective.

Chirone
Mar 8, 2009, 03:29 PM
On the other hand, if you connect (in IB) your ClassB* outlet in your instanceOfClassA to the actual instance of ClassB in your nib, then you will have what you want.

that's the problem... i don't understand how you do this

i thought maybe if i make a global instance of a ClassB* in the ClassA header file i could reference the object in IB, but i just lots and lots of compile errors (6000+) by including the ClassB header file in ClassA, errors that shouldn't occur because it never happened before

oh well... that's what happens when the person before doesn't do things right i guess....

never mind, i think i might have got it, and understand what you mean now

no wait... i don't understand... :\

oh wait no, it magically started working...

eddietr
Mar 8, 2009, 07:32 PM
that's the problem... i don't understand how you do this

i thought maybe if i make a global instance of a ClassB* in the ClassA header file i could reference the object in IB, but i just lots and lots of compile errors (6000+) by including the ClassB header file in ClassA, errors that shouldn't occur because it never happened before

oh well... that's what happens when the person before doesn't do things right i guess....

never mind, i think i might have got it, and understand what you mean now

no wait... i don't understand... :\

oh wait no, it magically started working...

Well, the connection to the B* outlet would be no different than a connection to, say, a UIButton*. So there are different ways to do this in IB, which I'm sure you are probably familiar with anyway just from connecting buttons and sliders and such.

"Magically" doesn't sound too good. :) Maybe get someone to look at your project (including the nibs) and make sure you're on the right track here.

Good luck with getting everything sorted out.

Chirone
Mar 8, 2009, 08:18 PM
but i like magic.... :p
nah it was just a typo i had in a method call...i got eager and pushed enter through all the auto completes and it picked the wrong thing to auto complete with ;)

thanks for all your help! greatly appreciated