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.
Related
I am new to ARC. My issue is that if we create a strong type property on a view controller, we need to make it nil once the navigation controller's popViewController happens.
Normally, we would do that in viewDidUnload. But in iOS 6 it's deprecated.
So where do we make that object nil? Apple says to do it in didReceiveMemoryWarning but that method does not get called every time when we pop the view controller.
Don't worry about it. Your properties will all get set to nil automatically by the Objective-C runtime in dealloc. This is true of all properties, not just outlets on a view controller.
You define a property strong if you want to keep ownership on the referenced object.
From what I can understand you probably need a weak property (when your object is released by someone else you don't need it and it can be deallocated) or maybe a workaround could be set it to nil in the viewDidDisappear method, but as Jim Puls said, without seeing you code mine are just educated guesses...
If you're popping/pushing between the same two view controllers, then the pointer in the UINavigationController shouldn't change as long as they don't get dealloc'ed. If they do get dealloc'ed then everything in them should get dealloc'ed too. You may end up creating new copies of these view controllers but that shouldn't be a problem because you're only creating new copies if the old ones were already dealloc'ed. The only way you can be retaining objects is if your view controllers (or objects within them) are referencing each other, causing them to be retained.
The difference between strong and weak is not that you need to manually set strong to nil. Rather, a strong relationship will cause an object to be retained, while a weak will not. That's why delegates are usually set to weak since you don't want a delegate retaining its parent (not parent exactly, but the object that it's a delegate of).
I have an interesting question about interface builder and ARC. I am building a view controller that will be initialized with a xib. I use the tap-and-drag capability of interface builder to create necessary property outlets for my xib. This initalizes the property as (weak, nonatomic). Sounds fine to me.
What's throwing me off is that lines such as [self setCategoryButton:nil]; are automatically added to viewDidUnload. I understand and used this before ARC. However, since these are weak references, wouldn't they automatically be cleared when the view unloads?
I suppose I could see the value in nil-ing these properties if those views are retained by other objects, but that seems an unusual case to me... Just wanted to get further feedback on the point.
Thanks,
Kurt
I filed a bug on this a while back, and the response that I got was that this is intentional behavior. Since Xcode cannot verify that there are no other strong references to the view, it cannot actually guarantee that the weak pointer would be automatically cleared in -viewDidUnload. Thus, they clear it for you.
Personally, I think this is a lame reason, but that's the reason that was given.
It will only be set to nil in iOS5 or later (iOS 4 does not automatically nil weak pointers), so it is there for safety in the auto generated code. I've been wondering about this myself and that's the only reason I can come up with.
From Documentation, the viewDidUnload
"This method ...is your chance to perform any final cleanup. ... "
"When a low-memory condition occurs and the current view controller’s views are not needed, the system may opt to remove those views from memory"
From Documentation, about weak (Setter Semantics)
Specifies that there is a weak (non-owning) relationship to the destination object.
If the destination object is deallocated,the property value is automatically set to nil.
So it's obvious. It's consistant on the rules.Is not about the object that your property points,but just nullify your property based on the above rule of weak.
The viewDidUnload suppose that's your weak property can't be point to any object,
because that object is deallocated (based on the place of viewDidUnload in the life cycle of a View Controller). And simply cleans it with the nil.
It's safe for you, explicit to the weak rule and memory efficient.
The compiler can't be sure that you took the care about the pointed object.
He just need to ensure the clean up.
Since the property is weak, the reference in your object won't affect the retain count of the object. So yes, there's no point in setting the object as nil. At least that's how I understand it.
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.
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.
Apple, for memory management issues, recommend defining outlets on properties, not in the attribute declaration. But, as far as I know, declaring properties exposes the class to external classes, so this could be dangerous.
On UIViewController we have the main view definition and the logic, so MVC is slightly cheated in this cases.
What is the beter approach, Apples's recommendation for memory-management or armored classes?
MVC isn't cheated by UIViewController, as that class implements a Controller. It defines connections between the View objects (usually stored in the XIB) and the Model objects (sometimes Core Data entities, sometimes other things).
Anyway. The point of defining outlets as properties is that you get to state explicitly what the memory management requirements on the properties are in the class interface. The NIB-loading mechanism uses the accessors if they exist, so you if you define a retain property, the outlet gets retained. If it can't find accessors it will set the instance variable directly.
Whether you define properties or not for your outlets is really a matter of personal taste. I do, because the outlets are set by an external object (the NSBundle class) so to my mind represent part of my view controller's API contract.
I believe you're thinking about this wrong.
Outlets only exist so that an external object, Interface Builder code and the nib decoders, can configure the instance of the class with the outlets. Hiding an outlet behind #protected or #private would defeat their entire purpose.
In good design this shouldn't be a problem because the view controllers should be relatively lightweight objects whose only function is to move data between the view and the model. The core logic of the app should be safely encapsulated in the model.
If you need a secure design, you can create the views programmatically and make them private but you lose all the flexibility and reuse that you get with outlets. It's a tradeoff.
In either case, however, this has nothing to do with memory management and properties. Whether a property is public, protected or private has nothing to do with how the properties memory is managed.