Re: Outlets / IBOutlet declarations (was Re: Interface Builder Wiring Objects)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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