I'm quite new to IOS so I'm sorry if my question is obvious.
I have set a ViewController's view in storyboard which contains other subviews.
In viewWillAppear I update these subviews depending on the object I passed to this ViewController. This object can have nil attributes and in this case I want to remove these subviews.
What is the right place to remove these subviews and is there a difference in terms of efficiency?
viewDidLoad
viewWillAppear
or viewWillLayoutSubviews ?
and will the constraints set to these removed objects also be removed?
Thx
The constraints will definitely be removed. However, it is possible to save the constraints in an array and add them back again in the future.
I would suggest making changes to the views( orientation, visibility, geometry ) in the viewWillLayoutSubviews method. You wouldn't want to do anything expensive in the ViewWillAppear method, because at that point the view is ready to be displayed to the user and it could impact how quickly the view appears to load for the user.
If you are using Storyboard and ARC do not worry about removing your views, conversely, if you are very interested to keep your memory under very tight control then do not use Storyboard and remove ARC.
What you refer to subviews are not subviews, the methods you listed are not UIView methods, and instead are UIViewController methods. However, if you have UIView objects that you are trying to remove, then those will also be handled for you. If you want more tight control, then declare them as public ivars, wrap them in #autoreleasepool {}, and set to nil in viewWillDisappear: or other method, or via delegate or notification pattern. It's relative to what you are doing and your conditions.
Related
At what point in the UIViewController lifecycle is the subview property of self.view guaranteed to be populated with all the correct views? Note: I don't care about if they're laid out or not, just that they exist in the subview array. WWDC videos say that loadView, viewDidLoad, and init all don't come with that guarantee but viewWillLayoutSubviews is also late in the game.
The task I'm trying to perform in this instance is localization. In a common view controller class, I want to loop through all the subviews, see if they have a custom attribute set that identifies what localized string key is attached to that view, and then recurse through all that views subviews until the bottom of the view hierarchy is reached. Layout isn't important in this instance, just that the subviews are populated in the view controller.
At what point in the UIViewController lifecycle is the subview property of self.view guaranteed to be populated with all the correct views
The earliest point implemented by most apps is viewDidLoad. At that point you are guaranteed that self.view exists along with all the subviews from the storyboard, and that any outlets hooked up to this view controller from the storyboard have been populated.
I don't care about if they're laid out or not, just that they exist in the subview array
Exactly so. self.view and its nib-loaded subviews exist at this point, but their layout has not yet taken place and their frame is not necessarily correct. You don't care, so viewDidLoad is fine for your purposes.
I have added multiples UIViews on outside of UIViewController and all views have week outlet connected. How can i Release memory of all view when pop to back ViewController.
First: Views (or other objects) on the top level of a xib should not have a weak kind of property in their corresponding view controller. Unlike view's in the view hierarchy, they don't have an owner after the xib is loaded and so they get deallocated anyway.
Now you seem to use ivars directly (why?), so I am actually not sure, but I don't think that makes a difference. Assuming Interface Builder accepts those as outlets and sets them, they're gone soon without an owner.
From that point of view, you've already saved memory...
Without knowing more about your project I can't tell, but the fact you're not asking for help on running into nil problems makes me guess you're taking ownership of these views somewhere else. To free them, you need to set whatever property (you are hopefully soon using properties for this) refers to them strongly to nil. ARC does the rest for you. Not using ARC? Start using it...
I would recommend to restructure this. Give the view controller (I guess that's some kind of FirstFlyerViewController) strong properties to the views (if you definitely need to have them outside the view hierarchy, otherwise, just add them as subviews somewhere). Use them, and once you pop the view controller and it gets dealloced (note that this is usually done by the framework and not yourself) they get freed along with it.
I'm new to IOS programming so I apologize if my question is obvious.
I created a UIViewController in storyboard, which contains a UIScrollView and multiple subviews.
These subviews (most often UITextViews) are filled with content from an external API, and content can thus be nil : in this case I would need to remove that subview which is empty.
For now I set this view as an IBOutlet and in viewDidLoad, if content is nil, I call
[self.thatView removeFromSuperView];
Is there a more efficient way to do that, for instance in loadView, in order to prevent that view to even load?
Is the usual method to handle subviews layoutSubviews?
Thx for your help
Any call before viewDidLoad will cause you problems unfortunately, you need to finish the load of a view before you dismiss it.
I have a UINavigationController with a UIViewController pushed onto it. In my viewControllers view, I have two subview UIScrollViews. I recreate these scrollviews every time in the viewWillAppear method in my viewController and add them as subviews to my viewcontroller's view. I am using ARC, should I be destroying the two scroll views in viewDidDisappear method? What is better practice for memory usage.
EDIT: I did some investigation, and without removing the scroll views and setting them to nil in the viewDidDisappear method, they are not released. The viewcontroller's view gets an increasing number of subviews as viewWillAppear is called. As I mentioned in the comments, I never deallocate my main viewcontroller. It always stays on the navigation controller's stack. Why must I manually release the scroll views?
It may not be necessary to do anything at all. If your UIViewController is removed from the screen and is then being deallocated, it will automatically deallocate its view hierarchy (including subviews you have added). An easy way to check for this is to override the dealloc methods of the classes you're interested in (using an ObjC Category method added to the class), and log a message to indicate they've been removed.
I'm constructing my view hierarchy through code and would like to know if it's better to create the entire hierarchy in loadView, when the view is requested from my controller, and then animate the views onto the screen in the viewWillAppear method, or if it's better to keep things simpler but potentially require more freeing and allocating of memory by building the entire hierarchy in viewWillAppear.
My understanding is that the controller calls loadView to create the view the first time it needs it, then keeps it around as long as it can so that you can leave and return to this controller and animate in the views, but not need to recreate and attach them, via viewWillAppear.
Basically, I'm finding it messy to be separately allocating the views in loadView and then transitioning (and sometimes updating the contents within) them in viewWillAppear, and wondering if the benefits of retaining the views don't outweigh the simplicity of simply recreating them (and consequently re-initializing them and avoiding any un-reset values).
loadView is called only once at the creation and should contation everithing to create the view.
viewWillAppear:(BOOL)animated is called everytime the view is displayed. If your view was retained, you can update/set your data in this. (Your UIButtons, UILabels,... are already allocated by loadView, you just set the content here.)