Re: Outlets / IBOutlet declarations (was Re: Interface Builder & Wiring Objects)
Re: Outlets / IBOutlet declarations (was Re: Interface Builder & Wiring Objects)
- Subject: Re: Outlets / IBOutlet declarations (was Re: Interface Builder & Wiring Objects)
- From: Jonathan Hess <email@hidden>
- Date: Mon, 17 Nov 2008 21:35:10 -0800
On Nov 18, 2008, at 1:11 PM, Roland King wrote:
Brian Stern wrote:
On Nov 17, 2008, at 11:35 PM, Roland King wrote:
Yes, but this is exactly the point. If I have no property for
an Outlet it's still retained. If I have a property for an
outlet that is assign, and not retain the outlet is still
retained, and I still must release it, even though I never
retained it.
When you say I can manage the outlets any way I like this is
wrong. They are managed for me. I want them to not be
retained. I don't have that option.
Now that I understand this I can live with it. But it still
makes no sense to me.
_______________________________________________
That's not what the documentation says and it's not my experience
either. The documentation says (section titled NIB Object
Retention) that each object in the NIB file is created with a
retain count of 1 and then autoreleased. Then they are hooked up
using setValue:forKey: which uses the setter method if it exists.
It also explicitly tells you that if you don't retain the array
of top-level objects you're going to lose them.
So if you have an outlet which is assign, and the setter method
is correct, the object will be created with retain count of 1,
autoreleased, then the setter method will be called and assign it
(no retain) and you do not have to release it. Why do you think
that you do?
I've done this, I have this exact patten in some of my iPhone
code, I have a delegate property which is assign and it is
assigned and it goes away when it's supposed to go away.
OK. The reason I believe that is because I fixed a massive memory
leak a couple days ago that I tracked down to this issue. I built
a simple test application that demonstrates that outlets that have
no properties or have assign properties are retained anyway and
must be released.
Here's my test project:
http://bellsouthpwp2.net/b/r/brians99/projects/TestPropertiesAndOutlets.zip
There are three labels that are outlets. One has a retain
property, one an assign property, and the third no property.
Unless they are released they are never dealloced. All three act
the same.
I'm a bit limited at work, no Mac here, so I took a look with
wordpad .. how nice.
You've defined the actual label pointers as IBOutlet, like this
IBOutlet MyLabel* mLabel1;
and then called the properties label1 etc.
in your .h file. When you hook them up in IB (I can't open that here
so I'm afraid I can't look) what is the name of the thing you bind
to, label1 or mLabel1? I think you'll find it's mLabel1 right? I
believe what you're doing is accessing the variables DIRECTLY in
each binding because you have defined those at outlets, not the
properties, and in that case yes they get retained as you know and
as the documentation says.
What I think you wanted was this
MyLabel *mLabel1;
@property( nonatomic, assign ) IBOutlet MyLabel *label1;
to define the PROPERTY as the outlet, not the variable.
I think if you'd written your own setters/getters instead of
synthesizing them, as I sometimes do when I really don't know who
the hell is calling me and when, you'd find they didn't get called.
I sometimes think that |accessInstanceVariablesDirectly is evil and
should be turned off.
I started off using properties and calling them something different
from variables because I was paranoid I'd access them directly, I've
sort of stopped that now as I mostly remember not to do that, but I
can understand why you'd want them differently named.
Normally instance variables and properties share the same name, so it
doesn't matter to Interface Builder where the 'IBOutlet' text appears.
If you're going to give your instance variables different names
though, you need to put the IBOutlet qualifier on the property if you
want it to be used.
In the above example, Interface Builder is going to use '[obj
setValue:someLabel forKeyPath:@"mLabel"]' which won't result in the
setter being used. The problem is the 'mLabel' for the keyPath instead
of 'label'.
The only thing that determines if Interface Builder uses a setter, or
accesses iVars directly is the presence of the setter, and the name of
the outlet. The name of the outlet is used as the keyPath in
setValue:forKeyPath:. The name of the outlet is the name of the
property or instance variable the IBOutlet modifier appears next to.
Interface Builder always calls setValue:forKeyPath:.
Jon Hess
Roland
|
_______________________________________________
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
_______________________________________________
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