Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-19 Thread mmalcolm crawford


On Nov 17, 2008, at 9:33 PM, Jeff Laing wrote:


How about:
http://developer.apple.com/samplecode/CacheInfo-MacOSX/listing1.html
(for example) which has the IBOutlet tag on the instance variables
rather than the properties; I'll bet its different because properties
and instance vars have the same name, isn't it?


No, it's because it hasn't been updated.


That example declares dozens of IBOutlet's, whose properties are
(nonatomic,retain) and doesn't release any of them in its dealloc.


That's a bug (filed).

mmalc

___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-19 Thread Brian Stern


On Nov 19, 2008, at 3:59 AM, mmalcolm crawford wrote:



On Nov 18, 2008, at 10:01 AM, Brian Stern wrote:

OK Erik, I'll bite.  What you describe above is correct as far as  
it goes.  However, when you say all the memory management is  
handled in one place, of course it's two.  The object has to be  
released.  The normal place to release objects is in their owner's  
dealloc method, and this also applies to outlets.


This is standard (best) practice for memory management.  It's not  
clear what the problem is here.
The only difference with outlets is that, if you don't follow best  
practice, you have to spend some time thinking about whether or not  
you have to release in dealloc (more on this below).


There are competing issues.  Following this best practice forces me to  
add public properties for all my outlets that my code never uses.   
This violates encapsulation and seems wasteful and error-prone.   
That's the reason I didn't do this earlier.  The one little paragraph  
in the documentation that addresses this says I 'should' do it this  
way but doesn't explain why.  I'll point out that the paragraph that  
explains memory management of outlets on Mac OS X on that page is half  
the length of the iPhone paragraph, and I'd maintain that the iPhone  
paragraph isn't long enough.


However, UIViewController has the ability to unload its view outlet  
in response to a memory warning.  Any subclass should also release  
its outlets in response to the memory warning, if the base class  
releases its view, but not otherwise.  So now there are three  
places to manage the memory of these outlets. The problem is that  
the base class doesn't always release its view in response to a  
memory warning and as far as I can tell the subclass has no clean  
way of telling if the view will be released or has been released.   
That's the problem.


You're shifting the goalposts; this is not the problem you  
originally described.


It's not me who has shifted the goalposts.  The whole playing field  
was moved out from under me when it was decided to retain outlets by  
default, which is different from how this all works on Mac OS X.


I'll admit that I was confused and probably a few other things a few  
days ago when I discovered that a huge memory leak was caused by  
outlets being retained behind my back.  And then I got a second kick  
in the shorts when I read your post pointing out that outlets need to  
be released in didReceiveMemoryWarning, which hadn't occurred to me  
was a side effect of their being retained.


In fact there have been several problems: You didn't understand the  
documentation as written; in testing the implementation of outlets  
you made a fundamental mistake; and -- as noted in my original  
message in this sub-thread -- the situation with outlets has  
heretofore been a mess.


You can add to your list of problems 'insufficient documentation and  
education of memory management of outlets.'  If you want to believe  
that I'm just one yokel developer who can't read and understand the  
documentation that's your right.  I'm sure I'm not the only one.




To reiterate points that Jon and Joar have made:

You shouldn't have to think about something as mundane as how do I  
manage memory for outlets?.  There are far more interesting issues  
for a programmer to spend their time on.


I couldn't agree with you more.

This is the reason for proposing a new best practice that will  
address all situations simply and easily.  *If* you know what you're  
doing -- and your experiment has shown that even relatively  
experienced developers may sometimes not know what they're doing  
-- then it is perfectly possible to deviate from the suggested  
pattern, but you then do this at your own risk.



I do, though, have to apologise for introducing a wrinkle (the  
problem of UIViewController's response to memory warnings) and then  
providing an incorrect solution.  I managed to mistake a question  
from some time ago for the answer -- mainly because I never received  
an answer.  I have now and can relay part of it (note to self: rdar://problem/5834347 
).


I guess even 'relatively experienced developers may sometimes not  
know what they're doing'



 There are several issues:

The template clearly indicates what should be done:


Obviously the client code can't touch _view or self.view in  
didReceiveMemoryWarning.  That's why I said upthread that there's no  
clean way for the client code to tell if the view will be unloaded or  
has been unloaded.



In theory, you should simply check whether the view has a superview:
but since _view is declared as @package, you can't do that.
You could invoke 'view':
but this has the disadvantages that (a) in some situations it will  
cause the view to be loaded before it is subsequently unloaded, and  
(b) it isn't future proof.


self.view will always be non-nil.

This is why I 'shifted the goalposts.'  There are many issues related  
to memory 

Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-19 Thread Greg Titus


On Nov 19, 2008, at 7:00 AM, Brian Stern wrote:


This leaves us for now with two solutions:
(a) Greg's (override setView:) which is more future-proof but is in  
many respects academically unsatisfying.
(b) For non-top-level-object, specify an assign attribute for the  
property -- and risk dangling pointers.


The override of setView is very similar to the viewDidUnload  
callback that I proposed as a solution for this.  It has its own  
further issues.  UIViewController calls [setView:nil] from its  
dealloc method so the subclass has to be prepared for this.  What  
I've done is to add all the public retain properties for all the  
outlets.  Additionally I've added a


-(void)releaseOutlets

method that uses the properties and sets them all to nil.  I call  
this method from my subclass's dealloc method and setView:  
override.  That way I only have one place to write the code that  
releases all the outlets.



Brian,

What is your reason for having a separate -releaseOutlets method to do  
this?


The sample that I gave (calling self.anOutlet = nil; when the argument  
to -setView: is nil) will do whatever releasing is required (if the  
anOutlet property is retain) or simple zeroing the pointer (if the  
anOutlet property is assign). The fact that UIViewController calls - 
setView:nil from its -dealloc is just additional convenience. All of  
your outlets get cleaned up at the same time as the UIViewController  
cleans up the main view. There is no need to write any outlet related  
code in your -dealloc at all, since it is all handled via the  
superclass and the -setView: override.


In short, the way I think of it, -setView: _IS_ the one centralized  
place that deals with all view-related pointers, including all  
outlets. And UIViewController calls -setView: at all the necessary  
times (setup, memory warning, dealloc), so you don't have to do  
anything else.


Hope this helps,
- Greg
___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-19 Thread Brian Stern


On Nov 19, 2008, at 10:29 AM, Greg Titus wrote:



On Nov 19, 2008, at 7:00 AM, Brian Stern wrote:


This leaves us for now with two solutions:
(a) Greg's (override setView:) which is more future-proof but is  
in many respects academically unsatisfying.
(b) For non-top-level-object, specify an assign attribute for the  
property -- and risk dangling pointers.


The override of setView is very similar to the viewDidUnload  
callback that I proposed as a solution for this.  It has its own  
further issues.  UIViewController calls [setView:nil] from its  
dealloc method so the subclass has to be prepared for this.  What  
I've done is to add all the public retain properties for all the  
outlets.  Additionally I've added a


-(void)releaseOutlets

method that uses the properties and sets them all to nil.  I call  
this method from my subclass's dealloc method and setView:  
override.  That way I only have one place to write the code that  
releases all the outlets.



Brian,

What is your reason for having a separate -releaseOutlets method to  
do this?


The sample that I gave (calling self.anOutlet = nil; when the  
argument to -setView: is nil) will do whatever releasing is required  
(if the anOutlet property is retain) or simple zeroing the pointer  
(if the anOutlet property is assign). The fact that  
UIViewController calls -setView:nil from its -dealloc is just  
additional convenience. All of your outlets get cleaned up at the  
same time as the UIViewController cleans up the main view. There is  
no need to write any outlet related code in your -dealloc at all,  
since it is all handled via the superclass and the -setView: override.


I think that you're probably right and that it's redundant.  Needless  
to say, mmalc's best practice has the outlets being released in  
dealloc.  That's why I had that code there in the first place.


FWIW, I don't think that UIViewController is documented as setting its  
view to nil from its dealloc method.  Frankly I don't know why it does  
it. I don't think it needs to.  It could certainly change in the  
future.  In fact another best practice (I think this is from mmalc) is  
to not set properties to nil in dealloc but to simply release them.   
If this changed the retained outlets would leak.


I don't feel strongly about this, but not having the release code in  
my dealloc method makes me a little nervous.  I do understand that my  
releaseOutlets method gets called twice when the object is being  
dealloced.


In short, the way I think of it, -setView: _IS_ the one centralized  
place that deals with all view-related pointers, including all  
outlets. And UIViewController calls -setView: at all the necessary  
times (setup, memory warning, dealloc), so you don't have to do  
anything else.


I certainly had never thought of any reason to override this accessor  
before this issue came up.  loadView and viewDidLoad are the normal  
override points for view creation and there are others for view  
appearance and disappearance, as I'm sure you know.  It's just that  
there's no comparable override point for the view being unloaded, even  
though that's a normal part of view controller life on iPhone.


Brian
___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-19 Thread Ricky Sharp


On Nov 19, 2008, at 10:13 AM, Brian Stern wrote:

I think that you're probably right and that it's redundant.   
Needless to say, mmalc's best practice has the outlets being  
released in dealloc.  That's why I had that code there in the first  
place.


FWIW, I don't think that UIViewController is documented as setting  
its view to nil from its dealloc method.  Frankly I don't know why  
it does it. I don't think it needs to.  It could certainly change in  
the future.  In fact another best practice (I think this is from  
mmalc) is to not set properties to nil in dealloc but to simply  
release them.  If this changed the retained outlets would leak.


But if your dealloc is like this...

- (void)dealloc
{
self.thisProp = nil;
self.thatProp = nil;
...
}

then you'll be calling the accessors and the right thing will happen  
(i.e. release if necessary).  This is what I currently do for all dev  
work (iPhone or Mac OS X).  In fact, I use accessors everywhere and  
never do direct ivar access.



I don't feel strongly about this, but not having the release code in  
my dealloc method makes me a little nervous.  I do understand that  
my releaseOutlets method gets called twice when the object is being  
dealloced.


This has been a very interesting read.  I currently do not have any  
special code in place to handle low-memory stuff.




In short, the way I think of it, -setView: _IS_ the one centralized  
place that deals with all view-related pointers, including all  
outlets. And UIViewController calls -setView: at all the necessary  
times (setup, memory warning, dealloc), so you don't have to do  
anything else.


I certainly had never thought of any reason to override this  
accessor before this issue came up.  loadView and viewDidLoad are  
the normal override points for view creation and there are others  
for view appearance and disappearance, as I'm sure you know.  It's  
just that there's no comparable override point for the view being  
unloaded, even though that's a normal part of view controller life  
on iPhone.



From Apple's template code, didReceiveMemoryWarning does have these  
code comments generated:


[super didReceiveMemoryWarning]; // Releases the view if it doesn't  
have a superview

// Release anything that's not essential, such as cached data


So, one should release all outlets that are tied to the view _iff_ it  
doesn't have a superview.  And then of course purge all support  
objects that would not be of any use.


If a view ends up not being loaded due to error warnings, it could be  
loaded at a later point in time.  Assuming there's enough memory at  
that point, your loadView will once again be called.


Personally, if any of my instances do get sent the  
didReceiveMemoryWarning message and there is no superview, I'll just  
purge everything.  I don't yet see any need to have only some objects  
live.


Having said that, I'll probably adopt the following:

- (void)dealloc
{
[self myCleanup];
[super dealloc];
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
if ([self.view superview] == nil)
{
[self myCleanup];
}
else
{
// in some cases, I lazily load objects (dictionarys, views,  
etc.)
// such objects could also be purged here.  If needed again,  
they'll be

// lazily loaded once more.
}
}

- (void)myCleanup
{
self.thisProp = nil;
...
}

___
Ricky A. Sharp mailto:[EMAIL PROTECTED]
Instant Interactive(tm)   http://www.instantinteractive.com



___

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]


RE: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-19 Thread Jeff Laing
 But if your dealloc is like this...
 
 - (void)dealloc
 {
  self.thisProp = nil;
  self.thatProp = nil;
  ...
 }
 
 then you'll be calling the accessors and the right thing will happen
 (i.e. release if necessary).  This is what I currently do for all dev
 work (iPhone or Mac OS X).  In fact, I use accessors everywhere and
 never do direct ivar access.

My understanding (and I'm a noob in this) is that best practices
recommend that you shouldn't start sending additional messages to an
object from inside its dealloc.

Those property accesses are just candy-coated calls to setThisProp:, etc
which violates the 'don't send message to yourself' recommendation.

Anyone want to clarify if it is/isn't safe to do this?  Certainly most
of the samples I've seen go out of their way to release instance
variables rather than nil properties, in their dealloc's

(This is the one thing I hate the *most* about properties - they really
feel glued on, at this point, rather than being a language feature that
the whole compiler knows about)
___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-19 Thread Brian Stern


On Nov 19, 2008, at 4:41 PM, Ricky Sharp wrote:



From Apple's template code, didReceiveMemoryWarning does have these  
code comments generated:


[super didReceiveMemoryWarning]; // Releases the view if it doesn't  
have a superview

// Release anything that's not essential, such as cached data

So, one should release all outlets that are tied to the view _iff_  
it doesn't have a superview.  And then of course purge all support  
objects that would not be of any use.


Having said that, I'll probably adopt the following:

- (void)didReceiveMemoryWarning
{
   [super didReceiveMemoryWarning];
   if ([self.view superview] == nil)
   {


The problem with this code is that the view accessor causes the view  
to be loaded if it's not already loaded.  So simply by asking for  
self.view.superview you may be causing your entire view hierarchy to  
be loaded in from the nib.  This doesn't seem to be a good thing to do  
inside a memory warning.  Besides that, the code you showed is wrong.   
You have to have the call to super at the end of the method after you  
call self.view.superview, otherwise you're guaranteeing that the view  
will be loaded every time your method is called.


This is not just an academic point.  The way that many iPhone apps are  
constructed with navbars means that you've got a root view and then  
one or more other view controllers that get pushed.  The root view  
will participate in all memory warnings for the life of the app and  
may be unloaded many times.  And that's all fine.  It just doesn't  
make any sense to load it in response to a memory warning.


That's why I said upthread that self.view will never be non-nil.

I'm starting to think that maybe using the assign properties is the  
better way to handle this.


--
Brian Stern
[EMAIL PROTECTED]



___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-19 Thread mmalcolm crawford


On Nov 19, 2008, at 7:00 AM, Brian Stern wrote:
There are competing issues.  Following this best practice forces me  
to add public properties for all my outlets that my code never  
uses.  This violates encapsulation and seems wasteful and error-prone.




No, it's not.  The nib-loading mechanism uses these methods.
It is precisely by using these methods that you avoid violation of  
encapsulation (notably on the desktop, where otherwise the instance  
variables may be set directly).
Further, as others noted, if you want to avoid declaring the  
properties publicly as read/write, you can declare then as read-only  
then re-declare them as read/write in a private extension.
Moreover it precisely avoids errors by providing a consistent pattern  
that will work across all platforms and that you can use without  
having to think about it.  As we seem to agree, having to think about  
how to declare/use outlets per se is a waste of mental effort.



That's the reason I didn't do this earlier.  The one little  
paragraph in the documentation that addresses this says I 'should'  
do it this way but doesn't explain why.


Because it should be obvious from a memory management perspective why  
this is the case.  And the documentation typically tries to avoid  
repeating the basic rules of memory management.



I'll point out that the paragraph that explains memory management of  
outlets on Mac OS X on that page is half the length of the iPhone  
paragraph, and I'd maintain that the iPhone paragraph isn't long  
enough.


I don't see what's missing from the iPhone discussion.  You're told  
that although the nib-loading mechanism doesn't retain the outlets  
directly, it uses KVC to set the outlets and what the ramifications  
are of that...



However, UIViewController has the ability to unload its view  
outlet in response to a memory warning.  Any subclass should also  
release its outlets in response to the memory warning, if the base  
class releases its view, but not otherwise.  So now there are  
three places to manage the memory of these outlets. The problem is  
that the base class doesn't always release its view in response to  
a memory warning and as far as I can tell the subclass has no  
clean way of telling if the view will be released or has been  
released.  That's the problem.


You're shifting the goalposts; this is not the problem you  
originally described.


It's not me who has shifted the goalposts.  The whole playing field  
was moved out from under me when it was decided to retain outlets by  
default, which is different from how this all works on Mac OS X.


No, it's not.  Again as the documentation points out, exactly what  
happens on Mac OS X depends on the context.  Most outlets are indeed  
not retained, but top-level objects *are* retained (so you do need to  
release them).  What The Nib Object Life Cycle doesn't mention --  
but probably should -- is that this is further complicated by what is  
the superclass of File's Owner -- if it's NSDocument,  
NSWindowController, or NSViewController, then you don't have to  
release top-level objects.


As I wrote originally, this is a mess, and requiring developers to  
think about this every time they make connections is unproductive.   
Which is why having a simple, consistent, approach that can be applied  
pervasively is beneficial.  As ever, you are free to deviate from that  
if you want to expend additional mental effort...



You can add to your list of problems 'insufficient documentation  
and education of memory management of outlets.'



It remains unclear in what respect the document is insufficient.


There are several issues:
The template clearly indicates what should be done:
Obviously the client code can't touch _view or self.view in  
didReceiveMemoryWarning.  That's why I said upthread that there's no  
clean way for the client code to tell if the view will be unloaded  
or has been unloaded.



Yes, there is...



In theory, you should simply check whether the view has a superview:
but since _view is declared as @package, you can't do that.
You could invoke 'view':
but this has the disadvantages that (a) in some situations it will  
cause the view to be loaded before it is subsequently unloaded, and  
(b) it isn't future proof.

self.view will always be non-nil.

[self.view superview] may, however, be nil, and this is what's  
important.
If you use this test, then you might temporarily load some unwanted  
objects which in the context of a memory warning is counter-productive  
but in most cases the overhead -- if any -- should be minor compared  
with the data you're expunging.  Nevertheless this is ultimately  
unsatisfactory.



This is why I 'shifted the goalposts.'  There are many issues  
related to memory management of outlets on iPhone.  Suggesting that  
everyone just follow your best practice described at the top  
obviously isn't sufficient.


On the contrary, following the best practice is sufficient, as 

Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-19 Thread j o a r


On Nov 19, 2008, at 1:57 PM, Jeff Laing wrote:


My understanding (and I'm a noob in this) is that best practices
recommend that you shouldn't start sending additional messages to an
object from inside its dealloc.



That is indeed correct. The official guideline is, AFAIK, to not call  
through your properties in init / dealloc.




Anyone want to clarify if it is/isn't safe to do this?  Certainly most
of the samples I've seen go out of their way to release instance
variables rather than nil properties, in their dealloc's



What makes it unsafe is that you might not control the implementation  
of the property setter method - A subclass could for example override  
it and make it not safe for use from init / dealloc.


That said, this might be something that the LLVM static analyzer could  
validate for us to the point where it would be OK.


j o a r


___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-19 Thread mmalcolm crawford


On Nov 19, 2008, at 1:57 PM, Jeff Laing wrote:

My understanding (and I'm a noob in this) is that best practices
recommend that you shouldn't start sending additional messages to an
object from inside its dealloc.


Correct.

(This is the one thing I hate the *most* about properties - they  
really
feel glued on, at this point, rather than being a language feature  
that

the whole compiler knows about)


It's not clear how this is relevant to the implementation of dealloc?

mmalc


___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-19 Thread Brian Stern


On Nov 19, 2008, at 5:11 PM, j o a r wrote:



On Nov 19, 2008, at 1:57 PM, Jeff Laing wrote:


My understanding (and I'm a noob in this) is that best practices
recommend that you shouldn't start sending additional messages to an
object from inside its dealloc.



That is indeed correct. The official guideline is, AFAIK, to not  
call through your properties in init / dealloc.




For whatever reason UIViewController sets its view property to nil  
from its dealloc method.  Greg's override of setView is based on this  
behavior.


--
Brian Stern
[EMAIL PROTECTED]



___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-19 Thread Michael Ash
On Wed, Nov 19, 2008 at 5:18 PM, mmalcolm crawford [EMAIL PROTECTED] wrote:

 On Nov 19, 2008, at 1:57 PM, Jeff Laing wrote:

 (This is the one thing I hate the *most* about properties - they really
 feel glued on, at this point, rather than being a language feature that
 the whole compiler knows about)

 It's not clear how this is relevant to the implementation of dealloc?

Because there's essentially no good way to dispose of properties given
the way that they're implemented.

If you set them to nil, then you fall afoul of overridden setters and the like.

If you manually release them, then you explode if you later change the
property from assign to retain or vice versa.

There should be a way to take advantage of the built-in property
mechanism to simply say do the right thing for this property,
ideally in a single call for an entire class, or even better yet
wholly automatically as part of NSObject's -dealloc implementation or
something. But instead, you get good support for synthesized setters
and getters but once you step into -dealloc you're back on your own,
losing a big part of the advantage, at least if you aren't willing to
hold your nose a bit and simply set them to nil despite the warnings
against it.

Mike
___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-19 Thread j o a r


On Nov 19, 2008, at 2:22 PM, Brian Stern wrote:

That is indeed correct. The official guideline is, AFAIK, to not  
call through your properties in init / dealloc.


For whatever reason UIViewController sets its view property to nil  
from its dealloc method.  Greg's override of setView is based on  
this behavior.



Please file bug reports whenever you find that our sample code and  
documentation are in conflict!


http://developer.apple.com/bugreporter/

Thanks,

j o a r


___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-19 Thread mmalcolm crawford


On Nov 19, 2008, at 2:29 PM, Michael Ash wrote:

On Wed, Nov 19, 2008 at 5:18 PM, mmalcolm crawford [EMAIL PROTECTED] 
 wrote:


On Nov 19, 2008, at 1:57 PM, Jeff Laing wrote:


(This is the one thing I hate the *most* about properties - they  
really
feel glued on, at this point, rather than being a language feature  
that

the whole compiler knows about)

It's not clear how this is relevant to the implementation of dealloc?

Because there's essentially no good way to dispose of properties given
the way that they're implemented.


I'm not sure why this is the case?
You send a release message to instance variables for which there is a  
corresponding retain or copy property.


If you set them to nil, then you fall afoul of overridden setters  
and the like.

If you manually release them, then you explode if you later change the
property from assign to retain or vice versa.


But you have the same problem without properties.
Except that it's worse; you could change the implementation of an  
accessor method (to assign rather than retain, for example), and you'd  
have no cross-check to make sure you then did the right thing in  
dealloc.


With properties, you have a clear set of statements that publicly  
declare what are the memory management semantics, and you can cross- 
check them with your dealloc method.



There should be a way to take advantage of the built-in property
mechanism to simply say do the right thing for this property,
ideally in a single call for an entire class, or even better yet
wholly automatically as part of NSObject's -dealloc implementation or
something.

That certainly might be a welcome feature -- I'd encourage you to file  
an enhancement request.



But instead, you get good support for synthesized setters
and getters but once you step into -dealloc you're back on your own,
losing a big part of the advantage, at least if you aren't willing to
hold your nose a bit and simply set them to nil despite the warnings
against it.

Again, this doesn't seem like a regression, it's just something that  
could perhaps be taken advantage of.  You've had to put up with worse  
up until now.


mmalc


___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-19 Thread mmalcolm crawford


On Nov 19, 2008, at 1:57 PM, Brian Stern wrote:

I'm starting to think that maybe using the assign properties is the  
better way to handle this.



That's certainly one approach, and one that was considered.

The problem is that you then have to think through every outlet  
declaration to make sure that you use the appropriate decorator, and  
you potentially run the risk of accessing dangling pointers --  
something that's typically going be a more significant issue than not  
disposing of an object at an opportune moment...


As noted previously, the goal with best practice here is precisely to  
relieve you of having to think about such banalities(*).
If you simply follow best practices, you get a good pattern that won't  
cause a crash and that allows you to concentrate on more important  
aspects of your application.


Dealing with memory warnings is a slightly special case that's arisen  
fairly early on in the lifetime of a new platform.
As an issue, it doesn't have any direct bearing on what is in general  
the best way to deal with outlets -- it's largely orthogonal.
It should be managed better than it is now, and hopefully it will be  
in the future.  In a way that doesn't require great mental effort to  
get right.


mmalc





(*) I'm grateful to Henry for having pointed me to an apposite  
quotation from Alfred North Whitehead:


It is a profoundly erroneous truism, repeated by all copy-books and  
by eminent people when they are making speeches, that we should  
cultivate the habit of thinking of what we are doing. The precise  
opposite is the case. Civilization advances by extending the number of  
important operations which we can perform without thinking about them.  
Operations of thought are like cavalry charges in a battle--they are  
strictly limited in number, they require fresh horses, and must only  
be made at decisive moments.

___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-19 Thread Ricky Sharp


On Nov 19, 2008, at 4:11 PM, j o a r wrote:



On Nov 19, 2008, at 1:57 PM, Jeff Laing wrote:


My understanding (and I'm a noob in this) is that best practices
recommend that you shouldn't start sending additional messages to an
object from inside its dealloc.



That is indeed correct. The official guideline is, AFAIK, to not  
call through your properties in init / dealloc.



I guess I really missed that part of the docs.

In all my desktop code, I always call my setters (non prop based) in  
dealloc:


[self setTitle:nil];
[self setColor:nil];
etc.


Just seemed natural to do self.title = nil, etc as I viewed properties  
as just a 1 to 1 replacement of manually setting stuff up.


Now, when you say call through your properties in init/dealloc, is  
that explicitly for things set up with @property?  Or, has what I've  
been doing all these years with calls to accessors in init/dealloc  
really bad?



In my case, I do have a decent amount of code being shared between  
platforms.  And, such code doesn't yet use properties.  After reading  
this thread, it's very temping to just rid myself of the properties  
and go back to rolling my own accessors as needed (I do have  
Accessorizer, so that task is not hard at all).


___
Ricky A. Sharp mailto:[EMAIL PROTECTED]
Instant Interactive(tm)   http://www.instantinteractive.com



___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-19 Thread j o a r


On Nov 19, 2008, at 3:05 PM, Ricky Sharp wrote:

Now, when you say call through your properties in init/dealloc, is  
that explicitly for things set up with @property?  Or, has what I've  
been doing all these years with calls to accessors in init/dealloc  
really bad?



There's no difference between setting through a property, and setting  
through a plain old setter method. That said, it's up to you to decide  
if you want to go with the official recommendation or not. If you  
think that you have enough control over the implementation of your  
accessor methods, you might choose to still use them.


j o a r


___

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]


RE: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-19 Thread Jeff Laing
On Nov 19, 2008, at 2:29 PM, mmalcolm crawford wrote:
 You send a release message to instance variables for which there is a
 corresponding retain or copy property.

which is why I originally said:
 (This is the one thing I hate the *most* about properties - they  
 really feel glued on, at this point, rather than being a language
feature  
 that the whole compiler knows about)

Most of the time you are supposed to think in terms of abstract
properties (so that KVO will work) but in your dealloc, you need to fall
back to worrying about the instance variables used to *implement* those
properties.

If you accept the default behaviour and name your properties the same as
your instance variables, then you don't necessarily notice that it's the
instance variables you clean up.  Its really easy to think that

- (void) frammitz { [something foobar]; }

and

- (void) frammitz { [self.something foobar]; }

are *identical* and they are not.  The Objective-C designers choice of
'.' syntax, which just *screams* structure-member-access to anyone with
C++ experience makes it even more confusing for those of us who have a
multi-language background.

The phrase for which there is a *corresponding* ... property is the
one I still need to repeat to myself over and over.  To a certain
extent, properties are orthogonal to instance variables; you can choose
to implement properties via equivalently named instance variables but
its not a given that you have to.  And you can have instance variables
without property definitions.

The @property declaration, where you use an alternate name, seems like
an area for confusion.

@property (nonatomic,retain) NSObject *xxx;
...
@synthesize xxx=_yyy;
...

not only defines accessors for a property called 'xxx', but also defines
the memory retention contract for the instance variable '_yyy'.  In the
past, you need only look in your .m file to determine how you needed to
clean up your instance variables irrespective of the public interface
they define in the .h file.  Now, you need to look in both the .h and
the .m 

As someone else remarked, @synthesize does *most* but not all of the
job, if its job is to 'provide the implementation of the property'.  The
reality is that its job is only to 'provide the *accessors* for the
property' which it does do completely.  And it does seem like having one
more hack, perhaps

- (void)dealloc
{
@release xxx;
[super dealloc];
}

would make me feel like the feature (properties) was actually complete.

Jeff Laing [EMAIL PROTECTED]

--
The lessons of history teach us - if they teach us anything - that
nobody learns the lessons that history teaches us.

___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-19 Thread Michael Ash
On Wed, Nov 19, 2008 at 5:41 PM, mmalcolm crawford [EMAIL PROTECTED] wrote:

 On Nov 19, 2008, at 2:29 PM, Michael Ash wrote:

 On Wed, Nov 19, 2008 at 5:18 PM, mmalcolm crawford [EMAIL PROTECTED]
 wrote:

 On Nov 19, 2008, at 1:57 PM, Jeff Laing wrote:

 (This is the one thing I hate the *most* about properties - they really
 feel glued on, at this point, rather than being a language feature that
 the whole compiler knows about)

 It's not clear how this is relevant to the implementation of dealloc?

 Because there's essentially no good way to dispose of properties given
 the way that they're implemented.

 I'm not sure why this is the case?
 You send a release message to instance variables for which there is a
 corresponding retain or copy property.

This does not qualify as good in my book. A fundamental of good
programming is once and only once. You've now described the
semantics of these properties in two different places in your code
and, worse, one of those places is implicit rather than explicit.

 If you set them to nil, then you fall afoul of overridden setters and the
 like.
 If you manually release them, then you explode if you later change the
 property from assign to retain or vice versa.

 But you have the same problem without properties.
 Except that it's worse; you could change the implementation of an accessor
 method (to assign rather than retain, for example), and you'd have no
 cross-check to make sure you then did the right thing in dealloc.

 With properties, you have a clear set of statements that publicly declare
 what are the memory management semantics, and you can cross-check them with
 your dealloc method.

This is true but I don't really see the point. I never said properties
were worse than manual accessors, just that this omission really hurts
their utility.

 There should be a way to take advantage of the built-in property
 mechanism to simply say do the right thing for this property,
 ideally in a single call for an entire class, or even better yet
 wholly automatically as part of NSObject's -dealloc implementation or
 something.

 That certainly might be a welcome feature -- I'd encourage you to file an
 enhancement request.

Duly noted.

 But instead, you get good support for synthesized setters
 and getters but once you step into -dealloc you're back on your own,
 losing a big part of the advantage, at least if you aren't willing to
 hold your nose a bit and simply set them to nil despite the warnings
 against it.

 Again, this doesn't seem like a regression, it's just something that could
 perhaps be taken advantage of.  You've had to put up with worse up until
 now.

I'm honestly not sure why you're using the word regression.
Certainly I never said it was one, and I don't believe Mr. Laing meant
to imply such either.

Mike
___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-18 Thread Brian Stern


On Nov 18, 2008, at 2:12 AM, Jonathan Hess wrote:

Which parts do you feel are contrary? I'm guessing it's that outlets  
with no setters are retained.


Yes, that's the root of the whole issue.  The fact is that outlets  
without setters that are retained aren't released by the code that  
retained them.  The responsibility for releasing them is implicitly  
passed on to some other code.  I misunderstood this after reading that  
paragraph a number of times because it is simply contrary to my  
understanding of Cocoa memory management.  I think it is contrary to  
the Cocoa memory management rules that the code that retains these  
objects isn't releasing them.


Now that I know that, there are still problems.  The outlets can be  
released in more than one place.  As mmalc mentioned, the view  
controller's view may be unloaded in response to a memory warning.   
However, the view won't be unloaded if the view controller is the  
frontmost view controller.  There's no simple way for a view  
controller subclass to know if it's the frontmost view controller or  
therefore if its view will be unloaded.  There is no viewDidUnload  
callback that would be the right place to release the outlets in this  
case.  The code that mmalc showed is not correct because it doesn't  
take into account the fact that the frontmost view controller won't  
unload its view.


In effect it is the UIViewController base class that is retaining the  
outlets, or causing them to be retained, when the nib is loaded.  But  
it abdicates responsibility for them.  The UIViewController base class  
is also the class that is releasing its view without any notification  
to the derived class that it should also release the outlets.


I haven't decided how I'm going to fix all this.  Either I'll add  
assign properties so the outlets are not retained or I'll release them  
all in viewDidLoad.


Most nib-loading on iPhone OS is done by UIViewController and I  
suppose most of my complaints above are with the UIViewController  
implementation.  In my code I would hardly ever have a reason to want  
to retain an outlet.  Having outlets be retained by default gives my  
code no benefit, and causes some complications.


--
Brian Stern
[EMAIL PROTECTED]



___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-18 Thread Erik Buck
If you write correct accessors for all outlets, then the retain/release memory 
management is entirely handled in one method.  the -set retains the new value 
and releases the old value.
 
Any confusion regarding memory management for IB outlets seems to stem from 
failure to write the accessors and reliance on syntactic sugar.  Just remember 
that 
 
@property (nonatomic, retain) IBOutlet UILabel *label;
 
results in synthesis of the appropriate accessor methods.  It does nothing more 
than save you some typing and document your intention.  The -set method that 
results from the above property declaration retains the new value and releases 
the old value.  The memory management is therefore all handled in one place 
just the way it should be and the way you want.
 
So what's the problem again ?
___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-18 Thread Brian Stern


On Nov 18, 2008, at 9:15 AM, Erik Buck wrote:

If you write correct accessors for all outlets, then the retain/ 
release memory management is entirely handled in one method.  the - 
set retains the new value and releases the old value.


Any confusion regarding memory management for IB outlets seems to  
stem from failure to write the accessors and reliance on syntactic  
sugar.  Just remember that


@property (nonatomic, retain) IBOutlet UILabel *label;

results in synthesis of the appropriate accessor methods.  It does  
nothing more than save you some typing and document your intention.   
The -set method that results from the above property declaration  
retains the new value and releases the old value.  The memory  
management is therefore all handled in one place just the way it  
should be and the way you want.


So what's the problem again ?


OK Erik, I'll bite.  What you describe above is correct as far as it  
goes.  However, when you say all the memory management is handled in  
one place, of course it's two.  The object has to be released.  The  
normal place to release objects is in their owner's dealloc method,  
and this also applies to outlets.


However, UIViewController has the ability to unload its view outlet in  
response to a memory warning.  Any subclass should also release its  
outlets in response to the memory warning, if the base class releases  
its view, but not otherwise.  So now there are three places to manage  
the memory of these outlets. The problem is that the base class  
doesn't always release its view in response to a memory warning and as  
far as I can tell the subclass has no clean way of telling if the view  
will be released or has been released.  That's the problem.


--
Brian Stern
[EMAIL PROTECTED]



___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-18 Thread Greg Titus

Brian,

The way to handle this is to _not_ respond to memory warnings in  
subclasses (at least not for the purposes of view outlet handling -  
there may be other non-view memory you want to free up in response to  
a memory warning). Instead, implement -setView: in your  
UIViewController subclass, and release outlets when the argument is  
nil. For example:


- (void)setView:(UIView *)aView;
{
if (!aView) {
self.anOutlet = nil;
self.anotherOutlet = nil;
self.thirdOutlet = nil;
}
[super setView:aView];
}

This will correctly clean up all of your outlets whenever the  
UIViewController unloads its view, and not otherwise.


Hope this helps,
- Greg

On Nov 18, 2008, at 10:01 AM, Brian Stern wrote:


OK Erik, I'll bite.  What you describe above is correct as far as it  
goes.  However, when you say all the memory management is handled in  
one place, of course it's two.  The object has to be released.  The  
normal place to release objects is in their owner's dealloc method,  
and this also applies to outlets.


However, UIViewController has the ability to unload its view outlet  
in response to a memory warning.  Any subclass should also release  
its outlets in response to the memory warning, if the base class  
releases its view, but not otherwise.  So now there are three places  
to manage the memory of these outlets. The problem is that the base  
class doesn't always release its view in response to a memory  
warning and as far as I can tell the subclass has no clean way of  
telling if the view will be released or has been released.  That's  
the problem.


--
Brian Stern
[EMAIL PROTECTED]



___

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/greg%40omnigroup.com

This email sent to [EMAIL PROTECTED]


___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-18 Thread Brian Stern

Thanks Greg,

That does work and has no bad side effects.  I can leave in the retain  
properties and release the outlets in the view controller's dealloc  
method.


Thanks,

Brian


On Nov 18, 2008, at 1:19 PM, Greg Titus wrote:


Brian,

The way to handle this is to _not_ respond to memory warnings in  
subclasses (at least not for the purposes of view outlet handling -  
there may be other non-view memory you want to free up in response  
to a memory warning). Instead, implement -setView: in your  
UIViewController subclass, and release outlets when the argument is  
nil. For example:


- (void)setView:(UIView *)aView;
{
if (!aView) {
self.anOutlet = nil;
self.anotherOutlet = nil;
self.thirdOutlet = nil;
}
[super setView:aView];
}

This will correctly clean up all of your outlets whenever the  
UIViewController unloads its view, and not otherwise.


Hope this helps,
- Greg

On Nov 18, 2008, at 10:01 AM, Brian Stern wrote:


OK Erik, I'll bite.  What you describe above is correct as far as  
it goes.  However, when you say all the memory management is  
handled in one place, of course it's two.  The object has to be  
released.  The normal place to release objects is in their owner's  
dealloc method, and this also applies to outlets.


However, UIViewController has the ability to unload its view outlet  
in response to a memory warning.  Any subclass should also release  
its outlets in response to the memory warning, if the base class  
releases its view, but not otherwise.  So now there are three  
places to manage the memory of these outlets. The problem is that  
the base class doesn't always release its view in response to a  
memory warning and as far as I can tell the subclass has no clean  
way of telling if the view will be released or has been released.   
That's the problem.


--
Brian Stern
[EMAIL PROTECTED]


___

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]


Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread mmalcolm crawford


On Nov 17, 2008, at 3:06 PM, mmalcolm crawford wrote:


Going forward, you're encouraged to declare outlets as follows:
@interface AppController : NSObject {
  NSTextField *myTextField;
  ...
}
@property (nonatomic, retain) IBOutlet NSTextField *myTextField;


Jeff asked (posted with permission):

One remaining question. Are you expected to release the outlet when  
your

controller is dealloc'd?  And did you have to prior to properties?
I believed the answer to the latter was no but I'm prepared to be
wrong on that..


Since the property is declared with the 'retain' attribute, the memory  
management semantics are made clear here.  Yes, you should release the  
outlet in dealloc.


The problem heretofor was that the story was a mess -- whether or not  
you released the outlet was dependent upon what class File's Owner  
inherited from, and whether or not you had accessor methods.  The  
principal advantage with the property-based pattern is that memory  
management is consistent across all classes across all patterns.  It  
will also work on modern runtimes that use instance variable synthesis  
(where there may be no instance variable declaration with which to  
attach the IBOutlet).


There may be some variation; if you have a delegate that may be  
connected using a delgate, then you may have:


@interface AppController : NSObject {
  id delegate;
  ...
}
@property (nonatomic, assign) IBOutlet id delegate;

although again use of a property declaration makes the memory  
management semantics clear (in this case you would of course not  
release delegate in dealloc).



One other consideration, particularly in iPhone applications, is where  
you might have outlets to subviews of a main view that might be  
released in sime situations -- e.g. a UIViewController whose view is  
released in didReceiveMemoryWarning. To ensure that you don't prolong  
the lifetime of objects you got from the nib, you should set (use your  
accessor methods to) set those variables to nil in the relevant  
method, e.g.:


@interface MyController : UIViewController {
  UILabel *label;
  ...
}
@property (nonatomic, retain) IBOutlet UILabel *label;

then

- (void)didReceiveMemoryWarning {
self.label = nil;
[super didReceiveMemoryWarning];
}


mmalc

___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread Brian Stern


On Nov 17, 2008, at 9:11 PM, mmalcolm crawford wrote:

One other consideration, particularly in iPhone applications, is  
where you might have outlets to subviews of a main view that might  
be released in sime situations -- e.g. a UIViewController whose view  
is released in didReceiveMemoryWarning. To ensure that you don't  
prolong the lifetime of objects you got from the nib, you should set  
(use your accessor methods to) set those variables to nil in the  
relevant method, e.g.:


@interface MyController : UIViewController {
 UILabel *label;
 ...
}
@property (nonatomic, retain) IBOutlet UILabel *label;

then

- (void)didReceiveMemoryWarning {
   self.label = nil;
   [super didReceiveMemoryWarning];
}


OK, this issue has come up for me very recently.  It appears that on  
iPhoneOS IBOutlets are retained, regardless of the presence of  
properties.  Even worse, in the presence of an assign property the  
outlet is still retained.  Whatever code is retaining the outlets  
never releases them.  So it seems that client code must release all  
outlets.


The documentation on this is vague, with a lot of 'should's and not  
clear statements of what really happens.  Actually this isn't (only)  
related to didReceiveMemoryWarning (which I hadn't considered related  
to this problem until you raised it).


Is this the way that things are supposed to work on iPhone OS?

--
Brian Stern
[EMAIL PROTECTED]



___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread Luke the Hiesterman


On Nov 17, 2008, at 7:12 PM, Brian Stern wrote:

OK, this issue has come up for me very recently.  It appears that on  
iPhoneOS IBOutlets are retained, regardless of the presence of  
properties.  Even worse, in the presence of an assign property the  
outlet is still retained.  Whatever code is retaining the outlets  
never releases them.  So it seems that client code must release all  
outlets.


Seems to me that the outlets must have a retain count of at least one  
when they're unarchived, as though they were alloc'd. It makes sense  
that the programmer should have to manually release objects in  
dealloc. How else would it happen?


Luke
___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread Brian Stern


On Nov 17, 2008, at 10:17 PM, Luke the Hiesterman wrote:



On Nov 17, 2008, at 7:12 PM, Brian Stern wrote:

OK, this issue has come up for me very recently.  It appears that  
on iPhoneOS IBOutlets are retained, regardless of the presence of  
properties.  Even worse, in the presence of an assign property the  
outlet is still retained.  Whatever code is retaining the outlets  
never releases them.  So it seems that client code must release all  
outlets.


Seems to me that the outlets must have a retain count of at least  
one when they're unarchived, as though they were alloc'd. It makes  
sense that the programmer should have to manually release objects in  
dealloc. How else would it happen?


IBOutlets are not necessarily top level objects.  Most are simply  
views that happen to be in the view hierarchy.  There will typically  
be one top level object in an iPhone nib.  This will be the view that  
belongs to UIViewController.  It is the UIViewController base class  
that loads the nib.  As long as it retains that top level view then  
all the subviews will also be retained.  They should be released when  
the UIViewController releases its view outlet.


Furthermore, NSBundle loadNibNamed:owner:options: on iPhone OS returns  
an array of the top level objects.  It would be trivial for the  
UIViewController base class object that is loading the nib to retain  
that array and of course release it in its dealloc.


If user code doesn't retain the outlets I don't understand why user  
code should be releasing those objects.



--
Brian Stern
[EMAIL PROTECTED]



___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread Brian Stern


On Nov 17, 2008, at 10:53 PM, Luke the Hiesterman wrote:



On Nov 17, 2008, at 7:46 PM, Brian Stern wrote:



On Nov 17, 2008, at 10:17 PM, Luke the Hiesterman wrote:



On Nov 17, 2008, at 7:12 PM, Brian Stern wrote:

OK, this issue has come up for me very recently.  It appears that  
on iPhoneOS IBOutlets are retained, regardless of the presence of  
properties.  Even worse, in the presence of an assign property  
the outlet is still retained.  Whatever code is retaining the  
outlets never releases them.  So it seems that client code must  
release all outlets.


Seems to me that the outlets must have a retain count of at least  
one when they're unarchived, as though they were alloc'd. It makes  
sense that the programmer should have to manually release objects  
in dealloc. How else would it happen?


IBOutlets are not necessarily top level objects.  Most are simply  
views that happen to be in the view hierarchy.  There will  
typically be one top level object in an iPhone nib.  This will be  
the view that belongs to UIViewController.  It is the  
UIViewController base class that loads the nib.  As long as it  
retains that top level view then all the subviews will also be  
retained.  They should be released when the UIViewController  
releases its view outlet.


Right, and view is a property of UIViewController. When you have  
your UIViewController release view, that is an example of the  
programmer releasing an outlet assigned from IB, which you seem to  
be arguing that the programmer shouldn't have to release objects  
given to it from IB.


Top.  Level.  Object.

Whatever code loads the nib is the owner of the array of top level  
objects and should retain them.  That object is UIViewController, not  
my subclass.


At any rate.  The problem is that this is poorly documented.

--
Brian Stern
[EMAIL PROTECTED]



___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread Roland King


OK, this issue has come up for me very recently.  It appears that  
on iPhoneOS IBOutlets are retained, regardless of the presence of  
properties.  Even worse, in the presence of an assign property the  
outlet is still retained.  Whatever code is retaining the outlets  
never releases them.  So it seems that client code must release  
all outlets.



Seems to me that the outlets must have a retain count of at least  
one when they're unarchived, as though they were alloc'd. It makes  
sense that the programmer should have to manually release objects  
in dealloc. How else would it happen?



IBOutlets are not necessarily top level objects.  Most are simply  
views that happen to be in the view hierarchy.  There will typically  
be one top level object in an iPhone nib.  This will be the view  
that belongs to UIViewController.  It is the UIViewController base  
class that loads the nib.  As long as it retains that top level view  
then all the subviews will also be retained.  They should be  
released when the UIViewController releases its view outlet.



Right, and view is a property of UIViewController. When you have your  
UIViewController release view, that is an example of the programmer  
releasing an outlet assigned from IB, which you seem to be arguing  
that the programmer shouldn't have to release objects given to it 
from  IB.


Luke

Exactly - most of the things you're hooking up in IB are your own 
objects, those outlets are just instance variables which are being set 
for you. It's your object, you have to deal with the lifetimes of the 
objects you refer to. I don't see why IB makes any difference, it's just 
calling setFoo: on some instance of your class, what you define setFoo 
to do is entirely up to you, but if it retains the argument, then you 
have to release it one day, in dealloc() would be the natural place.


The iPhone version of nib unarchiving and hookup seemed very consistent 
to me, it makes use of properties or setFoo: if you have them, allowing 
you to manage objects any way you like.


Perhaps the new @property() syntax makes it easy to forget about object 
lifetimes because it does the set/get/change automagically. These days 
when I add any property I go right to the dealloc method (and init if I 
have one) and ensure I've managed that property before I forget.

___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread Brian Stern


On Nov 17, 2008, at 11:05 PM, Roland King wrote:



OK, this issue has come up for me very recently.  It appears  
that  on iPhoneOS IBOutlets are retained, regardless of the  
presence of  properties.  Even worse, in the presence of an  
assign property the  outlet is still retained.  Whatever code is  
retaining the outlets  never releases them.  So it seems that  
client code must release  all outlets.



Seems to me that the outlets must have a retain count of at  
least  one when they're unarchived, as though they were alloc'd.  
It makes  sense that the programmer should have to manually  
release objects  in dealloc. How else would it happen?



IBOutlets are not necessarily top level objects.  Most are simply   
views that happen to be in the view hierarchy.  There will  
typically  be one top level object in an iPhone nib.  This will be  
the view  that belongs to UIViewController.  It is the  
UIViewController base  class that loads the nib.  As long as it  
retains that top level view  then all the subviews will also be  
retained.  They should be  released when the UIViewController  
releases its view outlet.



Right, and view is a property of UIViewController. When you have  
your  UIViewController release view, that is an example of the  
programmer  releasing an outlet assigned from IB, which you seem to  
be arguing  that the programmer shouldn't have to release objects  
given to it from  IB.


Luke

Exactly - most of the things you're hooking up in IB are your own  
objects, those outlets are just instance variables which are being  
set for you. It's your object, you have to deal with the lifetimes  
of the objects you refer to. I don't see why IB makes any  
difference, it's just calling setFoo: on some instance of your  
class, what you define setFoo to do is entirely up to you, but if it  
retains the argument, then you have to release it one day, in  
dealloc() would be the natural place.


The iPhone version of nib unarchiving and hookup seemed very  
consistent to me, it makes use of properties or setFoo: if you have  
them, allowing you to manage objects any way you like.


Perhaps the new @property() syntax makes it easy to forget about  
object lifetimes because it does the set/get/change automagically.  
These days when I add any property I go right to the dealloc method  
(and init if I have one) and ensure I've managed that property  
before I forget.


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.

___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread Luke the Hiesterman


On Nov 17, 2008, at 8:15 PM, Brian Stern wrote:

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.


I never said this. I compared having objects unarchived from a nib to  
being alloc'd, where the retain count is initially set to 1.


Luke
___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread Luke the Hiesterman


On Nov 17, 2008, at 8:17 PM, Brian Stern wrote:


I think it makes more sense to release the Outlets in viewDidLoad.


Why would you be releasing outlets when the view just loaded?  
Generally releasing happens when you're ready for something to go  
away

___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread Brian Stern


On Nov 17, 2008, at 11:20 PM, Luke the Hiesterman wrote:



On Nov 17, 2008, at 8:17 PM, Brian Stern wrote:


I think it makes more sense to release the Outlets in viewDidLoad.


Why would you be releasing outlets when the view just loaded?  
Generally releasing happens when you're ready for something to go  
away


There is an extra retain on the Outlets.  It is unneeded.  The outlets  
are sufficiently retained by the view hierarchy.


Either I have to release in both dealloc and in  
didReceiveMemoryWarning, or I can have them in viewDidLoad.


Release also is sent when you transfer ownership of an object to  
another object.  I don't wish to have ownership of the outlets.  They  
can be owned by the view hierarchy.  So if I release them in  
viewDidLoad then I don't have to release them in two other places,  
which is obviously error prone.


Don't you find it odd that you need to release outlets in  
didReceiveMemoryWarning?

___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread Roland King




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.

___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread mmalcolm crawford


On Nov 17, 2008, at 7:12 PM, Brian Stern wrote:


On Nov 17, 2008, at 9:11 PM, mmalcolm crawford wrote:

One other consideration, particularly in iPhone applications, is  
where you might have outlets to subviews of a main view that might  
be released in sime situations -- e.g. a UIViewController whose  
view is released in didReceiveMemoryWarning. To ensure that you  
don't prolong the lifetime of objects you got from the nib, you  
should set (use your accessor methods to) set those variables to  
nil in the relevant method, e.g.:


@interface MyController : UIViewController {
UILabel *label;
...
}
@property (nonatomic, retain) IBOutlet UILabel *label;

then

- (void)didReceiveMemoryWarning {
  self.label = nil;
  [super didReceiveMemoryWarning];
}


OK, this issue has come up for me very recently.  It appears that on  
iPhoneOS IBOutlets are retained, regardless of the presence of  
properties.


No, on iPhone outlets are consistently *not* retained -- which is  
precisely why you do need to retain top-level objects on iPhone. But  
absent accessor methods, connections are made using KVC...

This is documented here:
	http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/chapter_3_section_4.html#//apple_ref/doc/uid/1051i-CH4-SW6 




Even worse, in the presence of an assign property the outlet is  
still retained.  Whatever code is retaining the outlets never  
releases them.  So it seems that client code must release all outlets.


As I stated originally, following the pattern I describe above makes  
memory management consistent in all situations.



The documentation on this is vague, with a lot of 'should's and not  
clear statements of what really happens.




The documentation at	http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/chapter_3_section_4.html#//apple_ref/doc/uid/1051i-CH4-SW6 
 is explicit, there are just many different situations to consider  
if you don't follow the property pattern.


mmalc





Actually this isn't (only) related to didReceiveMemoryWarning (which  
I hadn't considered related to this problem until you raised it).


___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread Brian Stern


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.


--
Brian Stern
[EMAIL PROTECTED]



___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread mmalcolm crawford


On Nov 17, 2008, at 8:05 PM, Roland King wrote:

The iPhone version of nib unarchiving and hookup seemed very  
consistent to me, it makes use of properties or setFoo: if you have  
them, allowing you to manage objects any way you like.



This applies to both iPhone and Mac OS X/desktop.
This is why using properties simplifies matters...

mmalc

___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread mmalcolm crawford


On Nov 17, 2008, at 8:17 PM, Brian Stern wrote:

I think it makes more sense to release the Outlets in viewDidLoad.   
This way I only have to release them in one spot, not two.



No, it doesn't.
There is no sense at all in releasing outlets in viewDidLoad.
Follow the pattern I described and it's consistent...

mmalc

___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread mmalcolm crawford


On Nov 17, 2008, at 8:34 PM, Brian Stern wrote:

Don't you find it odd that you need to release outlets in  
didReceiveMemoryWarning?


Not at all -- assuming that you have a reference -- strong or weak --  
to an item in the user interface, you want to make sure you break it  
if the view is supposed to disappear.
If you have a strong reference you want to make sure that the item is  
disposed of when the other items from the nib go away; if you have a  
weak reference you want to make sure you don't send a message to a  
deallocated object (it'll go when the view goes...).


mmalc

___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread Brian Stern


On Nov 17, 2008, at 11:51 PM, mmalcolm crawford wrote:



On Nov 17, 2008, at 7:12 PM, Brian Stern wrote:


On Nov 17, 2008, at 9:11 PM, mmalcolm crawford wrote:

One other consideration, particularly in iPhone applications, is  
where you might have outlets to subviews of a main view that might  
be released in sime situations -- e.g. a UIViewController whose  
view is released in didReceiveMemoryWarning. To ensure that you  
don't prolong the lifetime of objects you got from the nib, you  
should set (use your accessor methods to) set those variables to  
nil in the relevant method, e.g.:


@interface MyController : UIViewController {
UILabel *label;
...
}
@property (nonatomic, retain) IBOutlet UILabel *label;

then

- (void)didReceiveMemoryWarning {
 self.label = nil;
 [super didReceiveMemoryWarning];
}


OK, this issue has come up for me very recently.  It appears that  
on iPhoneOS IBOutlets are retained, regardless of the presence of  
properties.


No, on iPhone outlets are consistently *not* retained -- which is  
precisely why you do need to retain top-level objects on iPhone. But  
absent accessor methods, connections are made using KVC...

This is documented here:
	http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/chapter_3_section_4.html#//apple_ref/doc/uid/1051i-CH4-SW6 



That's the vague documentation that I referred to.  What you're  
telling me is that where it says should in that paragraph it really  
means must.  OK, that's what I figured out a few days ago.


Where it says that it retains the object by default if no setter  
method is available, that seems to contradict what you say about  
outlets not being retained.  Actually I didn't really absorb that  
statement before.  It means that if there's no property then the  
outlet will be retained.  OK.


My experience with the assign property is contrary to what the docs  
seem to be saying.  I think the outlet is retained even if there is an  
assign property.


As I stated originally, following the pattern I describe above makes  
memory management consistent in all situations.


I simply don't need properties for all my Outlets, except for this  
issue.  I also don't really like making all my outlets implicitly  
public.  But I'm forced to do that.



--
Brian Stern
[EMAIL PROTECTED]



___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread Roland King

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.


Roland
|
___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread Luke the Hiesterman


On Nov 17, 2008, at 9:10 PM, Brian Stern wrote:

I simply don't need properties for all my Outlets, except for this  
issue.  I also don't really like making all my outlets implicitly  
public.  But I'm forced to do that.


You can use the readonly option for your properties. Alternatively,  
you can can declare a private setter.

___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread Luke the Hiesterman


On Nov 17, 2008, at 9:11 PM, Roland King wrote:

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.


Roland is correct. You've hooked up IB directly to the instance  
variables.

___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread mmalcolm crawford


On Nov 17, 2008, at 8:53 PM, Brian Stern wrote:


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.



It would help if you declared/connected your outlets correctly...

If you declare a property:

@property (nonatomic, assign) MyLabel *label1;

but make the connection in IB to mLabel1, then the property accessor  
isn't used.  So the outlet is set using setValue:forKey:.  Which  
results in the value being retained, precisely as described in the  
documentation...


http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/chapter_3_section_4.html#//apple_ref/doc/uid/1051i-CH4-SW6 



If you declare the the properties as I described:

@interface ViewControllerOne : UIViewController
{
MyLabel*mLabel1;
MyLabel*mLabel2;
IBOutlet MyLabel*   mLabel3;
}

@property (nonatomic, assign) IBOutlet MyLabel *mLabel1;
@property (nonatomic, retain) IBOutlet MyLabel *mLabel2;
// No property for label3

then you'll get the behaviour I described...


mmalc

___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread Brian Stern


On Nov 18, 2008, at 12:11 AM, 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.


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.



You're right.  I guess I didn't know there was a difference in the  
semantics based on the position of the IBOutlet.


In the end though I'm still pretty much forced to have properties for  
these outlets even though I don't want them.



--
Brian Stern
[EMAIL PROTECTED]



___

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]


RE: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread Jeff Laing
 If you declare a property:
 
 @property (nonatomic, assign) MyLabel *label1;
 
 but make the connection in IB to mLabel1, then the property accessor
 isn't used.  So the outlet is set using setValue:forKey:.  Which
 results in the value being retained, precisely as described in the
 documentation...
 

http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptu

al/LoadingResources/CocoaNibs/chapter_3_section_4.html#//apple_ref/doc/
 uid/1051i-CH4-SW6

How about:

http://developer.apple.com/samplecode/CacheInfo-MacOSX/listing1.html

(for example) which has the IBOutlet tag on the instance variables
rather than the properties; I'll bet its different because properties
and instance vars have the same name, isn't it?

(Note, this isn't the only one I've seen this pattern in, its just the
first that came to hand)

That example declares dozens of IBOutlet's, whose properties are
(nonatomic,retain) and doesn't release any of them in its dealloc.
___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread Jonathan Hess


On Nov 17, 2008, at 10:12 PM, Brian Stern wrote:



On Nov 17, 2008, at 9:11 PM, mmalcolm crawford wrote:

One other consideration, particularly in iPhone applications, is  
where you might have outlets to subviews of a main view that might  
be released in sime situations -- e.g. a UIViewController whose  
view is released in didReceiveMemoryWarning. To ensure that you  
don't prolong the lifetime of objects you got from the nib, you  
should set (use your accessor methods to) set those variables to  
nil in the relevant method, e.g.:


@interface MyController : UIViewController {
UILabel *label;
...
}
@property (nonatomic, retain) IBOutlet UILabel *label;

then

- (void)didReceiveMemoryWarning {
  self.label = nil;
  [super didReceiveMemoryWarning];
}


OK, this issue has come up for me very recently.  It appears that on  
iPhoneOS IBOutlets are retained, regardless of the presence of  
properties.
 Even worse, in the presence of an assign property the outlet is  
still retained.  Whatever code is retaining the outlets never  
releases them.  So it seems that client code must release all outlets.


The above statements are not true. On the iPhone, outlets are  
connected with setValue:forKeyPath:, and no explicit retention is done  
by the NIB unarchiving code. It maybe true that the objects are  
retained in some other fashion, independent of outlets. For example,  
when the MainWindow.nib is loaded by UIApplication, UIApplication  
explicitly retains the returned top level objects. That's a property  
of UIApplication, and doesn't really have anything to do with NIB  
loading in general. In the future, other nib loading classes may  
choose to do the same thing. If this is the situation you're referring  
to, and you're sending your outlet objects an extra release message,  
you're over releasing them.


The solution to a memory leak should never be an unbalanced release.  
You should use instruments and object alloc to determine exactly where  
the unbalanced retain is, and then balance it correctly. If you find a  
leak in framework code, you should file a bug, and you may consider  
over releasing it on your end for ballence, but if you choose to do  
that, you should do it with extreme caution. If there really is a leak  
in the framework code, then when it's fixed, you're unbalanced  
releases will start causing crashes.


The documentation on this is vague, with a lot of 'should's and not  
clear statements of what really happens.


If you ask specific questions about specific pieces of documentation,  
I'm sure that many readers would be happy to help you.


Jon Hess

Actually this isn't (only) related to didReceiveMemoryWarning (which  
I hadn't considered related to this problem until you raised it).


Is this the way that things are supposed to work on iPhone OS?


--
Brian Stern
[EMAIL PROTECTED]



___

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/jhess%40apple.com

This email sent to [EMAIL PROTECTED]


___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread Brian Stern


On Nov 18, 2008, at 12:13 AM, mmalcolm crawford wrote:



On Nov 17, 2008, at 8:53 PM, Brian Stern wrote:


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.



It would help if you declared/connected your outlets correctly...

//...

then you'll get the behaviour I described...


OK, fair enough.

You didn't address my other point regarding the memory warnings.  If  
the view controller is visible then it won't release the view  
hierarchy.  Your suggested code will null the outlet even though it  
still exists, resulting in bugs in some cases.



--
Brian Stern
[EMAIL PROTECTED]



___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread Jonathan Hess
Perhaps the new @property() syntax makes it easy to forget about  
object lifetimes because it does the set/get/change automagically.  
These days when I add any property I go right to the dealloc method  
(and init if I have one) and ensure I've managed that property  
before I forget.


Yes, but this is exactly the point.  If I have no property for an  
Outlet it's still retained.


Hey Brian -

Outlets for iPhone OS are established by calling setValue:forKeyPath:.  
The behavior of setValue:forKeyPath: is that if a setter exists, it is  
called. If a setter does not exist, the instance variable is looked up  
and set directly, and if it is an object, it is retained. This means  
that for IBOutlets, with no setters, they're retained in iPhone OS.  
This is different from Mac OS X. If you're writing code on both  
platforms, or are planning to, you should always use properties on  
both platforms since it makes the decision to retain outlets explicit  
and obvious.


Jon Hess
___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread Jonathan Hess


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 (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/jhess%40apple.com

This email sent to [EMAIL PROTECTED]



Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread Brian Stern


On Nov 18, 2008, at 12:34 AM, Jonathan Hess wrote:



The solution to a memory leak should never be an unbalanced release.


What I did to fix this was to add all of the properties to all of the  
outlets so they'd all be retained through those properties.  Then I  
added all the releases to all the deallocs to match those retains.


--
Brian Stern
[EMAIL PROTECTED]



___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread Jonathan Hess


On Nov 18, 2008, at 12:49 AM, Brian Stern wrote:



On Nov 18, 2008, at 12:35 AM, Jonathan Hess wrote:


Normally instance variables and properties share the same name,


Normally in your code maybe, not mine.

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.


I guess I just had a perfect storm of issues that made it appear  
that things were working differently from the way they were  
working.  My properties, though present, were ignored. The fact that  
it works differently from Mac OS makes it worse.


Which difference are you referring to? It sounds like you're referring  
to the fact that if a setter doesn't exist the variable is retained by  
setValue:forKeyPath:. To avoid implementing setters, you're free to  
them out and let IB directly set you're iVars. If you do that, you'll  
just need to release them in dealloc. The best practices are there to  
help developers who are new to both platforms. If you feel that you  
have an adequate understanding of how the outlets are established,  
you're free to use a pattern that you prefer.


Jon Hess




Thanks for the help guys.

--
Brian Stern
[EMAIL PROTECTED]



___

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/jhess%40apple.com

This email sent to [EMAIL PROTECTED]


___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread Jonathan Hess


On Nov 18, 2008, at 12:49 AM, Brian Stern wrote:



On Nov 18, 2008, at 12:35 AM, Jonathan Hess wrote:

Perhaps the new @property() syntax makes it easy to forget about  
object lifetimes because it does the set/get/change  
automagically. These days when I add any property I go right to  
the dealloc method (and init if I have one) and ensure I've  
managed that property before I forget.


Yes, but this is exactly the point.  If I have no property for an  
Outlet it's still retained.


Hey Brian -

Outlets for iPhone OS are established by calling  
setValue:forKeyPath:. The behavior of setValue:forKeyPath: is that  
if a setter exists, it is called. If a setter does not exist, the  
instance variable is looked up and set directly, and if it is an  
object, it is retained. This means that for IBOutlets, with no  
setters, they're retained in iPhone OS. This is different from Mac  
OS X. If you're writing code on both platforms, or are planning to,  
you should always use properties on both platforms since it makes  
the decision to retain outlets explicit and obvious.


How come the documentation that mmalc quoted doesn't have this clear  
statement?


Hey Brian -

Check out Table 2-1. It states all of this explicitly.

Jon Hess








Jon Hess


--
Brian Stern
[EMAIL PROTECTED]



___

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/jhess%40apple.com

This email sent to [EMAIL PROTECTED]


___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread Brian Stern


On Nov 18, 2008, at 12:59 AM, Roland King wrote:





Hey Brian -

Outlets for iPhone OS are established by calling   
setValue:forKeyPath:. The behavior of setValue:forKeyPath: is  
that  if a setter exists, it is called. If a setter does not  
exist, the  instance variable is looked up and set directly, and  
if it is an  object, it is retained. This means that for  
IBOutlets, with no  setters, they're retained in iPhone OS. This  
is different from Mac  OS X. If you're writing code on both  
platforms, or are planning to,  you should always use properties  
on both platforms since it makes  the decision to retain outlets  
explicit and obvious.



How come the documentation that mmalc quoted doesn't have this  
clear  statement?



which one did he quote, the one I suggested to you has it .. it's  
under Nib Object Retention. It's a page I have bookmarked because as  
I switch between iPhone and regular OSX I like to remind myself what  
it says. It's pasted below.


Yes, that's it.  I've read it plenty of times.





iPhone OS - managed memory model

Objects in the nib file are created with a retain count of 1 and  
then autoreleased. As it rebuilds the object hierarchy, however,  
UIKit reestablishes connections between the objects using the | 
setValue:forKey:| method, which uses the available setter method or  
retains the object by default if no setter method is available.


I admit that I didn't internalize this statement because the behavior  
is different from the Mac.  I also didn't internalize this because it  
seems to contradict the standard Cocoa memory management rules.  My  
code doesn't retain the outlets so it shouldn't have to release them.


If you define outlets for nib-file objects, you should also define a  
setter method for accessing that outlet.


Why SHOULD?


Setter methods for outlets should


Why SHOULD?

retain their values, and setter methods for outlets containing top- 
level objects must retain their values to prevent them from being  
deallocated. If you do not store the top-level objects in outlets,  
you must retain either the array returned by the | 
loadNibNamed:owner:options:| method or the objects inside the array  
to prevent those objects from being released prematurely.


In a nib loaded by UIViewController I have no access to the top level  
objects array so this isn't usually relevant.


The shoulds in there confused me.  The fact that the behavior is  
different from the Mac confused me.  The fact that the behavior seems  
contrary to standard Cocoa memory management rules confused me.  I  
assure you that I'm not the only person confused by this and who  
doesn't understand this.

___

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]


Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)

2008-11-17 Thread Jonathan Hess


On Nov 18, 2008, at 1:14 AM, Brian Stern wrote:



On Nov 18, 2008, at 12:59 AM, Roland King wrote:





Hey Brian -

Outlets for iPhone OS are established by calling   
setValue:forKeyPath:. The behavior of setValue:forKeyPath: is  
that  if a setter exists, it is called. If a setter does not  
exist, the  instance variable is looked up and set directly, and  
if it is an  object, it is retained. This means that for  
IBOutlets, with no  setters, they're retained in iPhone OS. This  
is different from Mac  OS X. If you're writing code on both  
platforms, or are planning to,  you should always use properties  
on both platforms since it makes  the decision to retain outlets  
explicit and obvious.



How come the documentation that mmalc quoted doesn't have this  
clear  statement?



which one did he quote, the one I suggested to you has it .. it's  
under Nib Object Retention. It's a page I have bookmarked because  
as I switch between iPhone and regular OSX I like to remind myself  
what it says. It's pasted below.


Yes, that's it.  I've read it plenty of times.





iPhone OS - managed memory model

Objects in the nib file are created with a retain count of 1 and  
then autoreleased. As it rebuilds the object hierarchy, however,  
UIKit reestablishes connections between the objects using the | 
setValue:forKey:| method, which uses the available setter method or  
retains the object by default if no setter method is available.


I admit that I didn't internalize this statement because the  
behavior is different from the Mac.  I also didn't internalize this  
because it seems to contradict the standard Cocoa memory management  
rules.  My code doesn't retain the outlets so it shouldn't have to  
release them.


If you define outlets for nib-file objects, you should also define  
a setter method for accessing that outlet.


Why SHOULD?


So that it's obvious to the reader of the code what is retained, and  
what isn't. If you have setters then you can easily look at the .m  
file and verify that the retains and releases are all balanced without  
having to know anything else.



Setter methods for outlets should


Why SHOULD?


You're free to have an outlet be non-retained, it's up to you. The  
same rules should apply to outlets that apply to other instance  
variables. You should retain your instance variables so they don't go  
away when you don't expect them to. You just have to watch out for  
creating cycles. If you do create a cycle, you can either break it  
explicitly, or you can use some non-retained instance variables.





retain their values, and setter methods for outlets containing top- 
level objects must retain their values to prevent them from being  
deallocated. If you do not store the top-level objects in outlets,  
you must retain either the array returned by the | 
loadNibNamed:owner:options:| method or the objects inside the array  
to prevent those objects from being released prematurely.


In a nib loaded by UIViewController I have no access to the top  
level objects array so this isn't usually relevant.


The shoulds in there confused me.  The fact that the behavior is  
different from the Mac confused me.  The fact that the behavior  
seems contrary to standard Cocoa memory management rules confused me.


Which parts do you feel are contrary? I'm guessing it's that outlets  
with no setters are retained. If that's the case, you might consider  
thinking of it this way: Interface Builder for the iPhone uses key  
value coding. That's really the truth of the matter and accurately  
describes everything that is going on. That outlets without a setter  
are retained is a side effect of using key value coding. Additionally  
having the outlet retain by default, and making that be the  
recommendation when you use properties or setters comes into balance  
with the fact you don't have to send a release massage to each top  
level nib object after loading a NIB on the iPhone. With that, the  
memory management rules for NIB loading on the iPhone actually pretty  
concise:


	1. Outlets are set with key value coding - implies outlets with no  
setters are retained.

2. If you retain an outlet, you must release it.
	3. If you want something to stay alive after the call to  
loadNibNamed: you need to retain it in some way.


There really isn't anything in that list that is out of line with  
Cocoa memory management patterns.


Also, just incase you aren't familiar with it, here's a link to the  
key value coding programming guide: http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/


Good Luck -
Jon Hess

 I assure you that I'm not the only person confused by this and who  
doesn't understand this.

___

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