This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Do I need to release xib resources?
IBOutlet WeaponStoreViewTableCell *tblCell;
I have this instance variable in my code. It is tied to a NIB using interface builder. Do I need to throw a release for this in my dealloc method?
The way this is handled in iOS apps and Mac OS Apps seems to be difference, the underlining rule for retain/release are the same but iOS apps tend to use properties with (retains) properties to connect them to the item in you nib files so in this case you have to release to balance the retain from you property. In mac OS X the practice seems to be connect the interface elements straight to you ivars, which is a straight assign, in the situation you don, t have to blance with a release because the interact elements is retains by you NSNib object with is retains by you NSWindowController class so all of that is angled for you. My personnel feeling is that I attach interface elements straight to the ivar, so I don't have to release them myself I will then have a property which is readonly since I vary rarely want to change an interface ivar once it has been set by the nib but this really is all just a matter of personnel style.
The general rule is if you retain it (or it's retained on your behalf), you release it. If you declare a property (with retain specified) for the cell, then it gets retained on your behalf, and you need to (somehow) release it. If you don't then not.
Related
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Should IBOutlets be strong or weak under ARC?
I read about ARC briefly and thought ok, everything is strong and delegate is weak.
Now I'm creating a view in interface builder and making IBOutlets, and Xcode's default setting is set to weak.
There seems to be a reason for this suggestion, is there a reason most IBOutlets would want weak property?
Is that because these views(IBOutlets) are already retained because they are attached to its superview? and we seldom replace IBOutlet views?
But I don't see a harm in setting it as strong, is there a problem with it?
For a discussion of why IBOutlet references should be weak, see the Resource Programming Guide: Nib Files. I quote from the guide:
Outlets should generally be weak, except for those from File’s Owner to top-level objects in a nib file (or, in iOS, a storyboard scene) which should be strong. Outlets that you create should therefore typically be weak, because:
Outlets that you create to subviews of a view controller’s view or a window controller’s window, for example, are arbitrary references between objects that do not imply ownership.
The strong outlets are frequently specified by framework classes (for example, UIViewController’s view outlet, or NSWindowController’s window outlet).
For my own two cents, I make things strong if I own it, or I need a strong reference in case the owner goes away and I need it to be retained, neither of which apply here. So, rather than asking, "why can't I make it strong?", I'd ask "why would I want to make it strong?" If there's no good reason to do so, I'd let Interface Builder do it's thing and make it weak.
It's just preference. The rationale for weak or assign is that the superviews, controllers, etc will hold strong references during the object's lifetime within that graph.
Personally, I am old school, and favor strong references -- even in this scenario. At times, using strong references means you may need to explicitly destruct components of your objects' subgraphs (e.g you must 'break' all circular dependencies when tearing down). I only use weak in very exceptional circumstances because I favor consistency; There are fewer variables at play when/if when something goes wrong and when reading programs.
I understand the ARC Release Notes, however I have been wondering what does this mean exactly and what are the system classes:
You may implement a dealloc method if you need to manage resources other than releasing instance variables. You do not have to (indeed you cannot) release instance variables, but you may need to invoke [systemClassInstance setDelegate:nil] on system classes and other code that isn’t compiled using ARC.
This is right here ARC Release Notes under the new rules enforced by ARC
What are the so called system classes here?.
I take this to mean any class starting with 'NS' or 'UI'. Apple have not rebuilt all the frameworks from the ground up to use ARC. Instead, your new ARC code should happily interoperate with the existing frameworks if you follow the rules.
In particular, delegate properties of system classes (such as UIApplication) are still declared as (nonatomic, assign) instead of (nonatomic, weak). This means that these properties do not automatically zero themselves when the delegate is deallocated. In fact, assign is a synonym for unsafe_unretained under ARC. Hence the advice to manually nil the delegate property in your dealloc method. This is so that there is no chance that the system class will attempt to access its delegate after it has disappeared.
Under ARC, what's the point of making every IBOutlet a property? What would be the downside of using ivars for IBOutlets used only internally by the view controller?
If you don't use the setter/getter methods for anything, don't rely on key-value observing for those properties, and don't anticipate that a subclass would benefit from overriding those properties, then there's no real downside to just using ivars for IBOutlets under ARC.
I've been using ivars for my "private" IBOutlets and ran into memory leak problems. I think it's because my IBOutlets used the __unsafe_unretained attribute instead of __weak. I can't use __weak because it's not supported on iOS 4 (I want my app to be backwards compatible with iOS 4). It's difficult to grasp what's really happening with ARC, IBOutlets, viewDidUnload, and all that mess. Sigh...
Anyways, when I changed my IBOutlets from ivars to properties, the memory leak issues went away.
So, to answer my own question, one downside of using ivars for IBOutlets is that you might run into memory leaks if you have the __unsafe_unretained attribute.
I have been developing for iPhone from last 1-2 months and all the time for taking IBOutlet I use the following method to declare any property:
In .h files:
#interface ....
{
controlType varName;
}
#property() IBOutlet controlType varName;
In .m files:
at top -#synthesize varName;
in delloc method - [varName release];
Although the method is good but it isn't very good when its taking a couple of minutes just for declaring property.
Is there any automatic process for declaring properties, IBOutlets, IBActions or basic data variables.
I hope there should be some automatic methods for this scenario as this is a very basic process.
Thanks all.
Another one that not many people are aware of is that you can drag from Interface Builder to your header file to create IBActions or IBOutlets.
NOTE: Open the Assistant Editor with focus on the XIB inside IB.
If you create your IBOutlets this way Xcode automatically adds the property, synthesizes it, sets it to nil in viewDidUnload and releases it in dealloc.
You simply drag from the IB object to your header file the same way you would when creating connections between the view objects and their file owners (screenshot below).
In fact, yes!
You no longer need to declare the actual iVar.
In short, simply leave out this part: controlType varName;
For now, you do still need to explicitly "synthesize".
(As far as I can see, they could possibly automate that in the future. But for now you have to "synthesize" to create the setter and getter.)
You do still have to release the memory - there's really no way that could be automated, as memory handling is "real he-man programming."
For any new chums reading, don't forget the "self." part when using the property.
Plus note that XCode4 even has a new automatic thingy. Simply drag from the interface builder, to your .h file, and it will do everything for you -- try it!
In answer to your suplementary question: An IBOutlet DOES NOT PARTICULARLY NEED TO BE a property - you can just use a normal cheap iVar. On the other hand, if you wish, to you can use a property. Furthermore: you can even use the new trick (2011) of not bothering to declare the ivar, just use the property declaration, and shove an IBOutlet in there!
There is an awesome tool that speeds the whole process up: accessorizer.
You write controlType varName; select it and press some buttons and accessorizer will create the property, init, dealloc, viewDidUnload and much more for you. You just have to paste the code into your project.
Try it, a demo is available.
You can save yourself having to release the object by changing the property declaration. If you use:
#property (assign) IBOutlet controlType varName;
retain wont be called on your view so you wont have to release it later. This is generally safe as views are retained when they are added to a parent. If you are removing the views from their parent for some reason then you will have to retain them.
Here's an xcode script to automate the tedium of declaring properties.
I use a .xib to layout my viewController and have 10 IBOutlet objects that IB uses, none of them have #properties assigned to them (no #property(retain) IBOutlet...). When I release the viewController none of those objects are being released, I have to manually release them in the dealloc of the viewController.
This doesn't seem like normal behavior, I thought that those objects would be released by the system since IB is whats assigning them, what could I be doing wrong?
Apple's Memory Management Programming Guide tells you exactly how to properly release IBOutlets.
In short, you are supposed to release them in dealloc, but you also want to release them in viewDidUnload.