I am new in Swift and IOS programing
I want to know how I remove my modal ViewController from memory ram.
This kind that I use to open.
let vc = self.storybordar?.instantieteViewController(withIndentifier:"indentifier") as UIViewController
self.present(vc,animated:true,completion:nil)
And I remove so
self.dissmiss(animated:true,completion:nil)
My controller until closed but my memory not change
What happinig is when I open my modal my memory increases and when a I close my memory doesn't decrease.
Swift uses automatic reference counting for memory management. Objects will be released from memory if no references to them exist anymore.
You can remove a reference by setting a variable referencing the object to nil.
vc = nil
or by using weak references whenever possible.
If you dismiss the view controller, you have to make sure, there are no references left or it will not be released from memory.
Also, iOS may keep some data around. Just make sure, that memory usage does not grow significantly on subsequent presentations of your view controller. Only then you may have a reference cycle.
Related
I'm using the following code to push a new view controller into the stack, the ViewController is initalised with an nib and only contains a webview, the class is completely empty.
var profileVC = GenericWebViewController()
profileVC.initWithURL(url)
navigationController.pushViewController(profileVC, animated:true)
When the view is pushed, memory usage goes up, however, when the back button is pressed, the memory level does not go down.
What should I do to get profileVC garbage collected?
Nothing ;)
Automatic reference counting automatically handles this for you
http://clang.llvm.org/docs/AutomaticReferenceCounting.html
Edit: The memory may not be going down for other reasons. Check you don't have any strong reference cycles. To be 100% sure your GenericWebViewController is being cleared from memory, override its dealloc method and make sure it's being called.
Also check out the leaks instrument
I want to switch between two view controllers which containes lot of imageviews and other image content. When i switch back to another view controller memory is not released. When i go back same amount of memory will be loaded again. Following is how i switch to another viewcontroller.
MainViewController *mView = [self.storyboard instantiateViewControllerWithIdentifier:#"main_view_controller"];
lView.modalTransitionStyle= UIModalTransitionStyleCrossDissolve;
[self presentViewController:mView animated:YES completion:nil];
Can anyone help me find a way which will release memory when switching back to another viewcontroller. Thanks in advance.
The cause of this is that you have some retained ivars that's being referenced from/to another class for example.
By using release on an object, that objects reference count is decreased by one. So if your class have a higher reference count than 1 (in a perfect example. In a real implementation this will differ), it will not be released.
Be sure to set the view to nil also. One thing that might make your view to retain is if you for example have a timer or observer in your "MainViewController". Then, if using release on that class, the reference count will still be higher than 0 and thus your view will never be released.
Instruments is a good tool you can use to find scenarios like yours in your program. Find out more How to use Instruments - RayWenderlich.com
I'm pushing and popping ViewControllers in UINavigationController.
I'm tracking the memory consumption of my app.
While pushing the new viewController the memory consumption is increasing gradually, but when I'm popping the same ViewController using [self.navigationController popViewControllerAnimated:NO]; the memory consumption does not decrease but the constant.
That particular viewController can be pushed and popped by user many times which can lead the high memory consumption of app in RAM.
What should I do to optimise my memory consumption?
When you dismiss a view controller (or pop it), it will be deallocated if you didn't make any strong pointers to it (that controller is retained by the navigation controller, or the presenting view controller, so you usually don't need to have a pointer to it when you create it and push or present it).
It will be be released if there are no other strong pointers to it
Try to avoid using strong properties for IBOutlets.
Consider reviewing whether you are referencing self in a block. If you do, you risk holding onto the UIViewController reference after you have popped it.
For a more in-depth review of why, check out this answer:
How do I avoid capturing self in blocks when implementing an API?
If your app design allows the user to push and pop the same view controller over and over again, you may want to look at reusing the same view controller and just updating its contents each time it's pushed.
Instead of creating and destroying it over and over, create one, set up its contents and push, when it's popped, keep it around ready to be shown again. Next time it needs to be shown, update its contents and then push it again.
I would like to say, that my last few days were spent on searching the web for my app memory problem. I was switching between 2 UIViewControllers. One of them had a scroll view which kept all subviews on it. It turned out that that UIVC loads a new scroll view without releasing the previous one. It took me several hours to realize it.
What I did was:
Looking for any kind of deadlocks inside the app, then searching for every variable that had a strong atributte and other desperate measures. But what really worked was:
#IBAction func backBB(sender: UIBarButtonItem) {
collectionView.removeFromSuperview()
self.frontView.removeFromSuperview()
eventsPhotos.removeAll(keepCapacity: false)
symbolContainerView.removeFromSuperview()
self.myScrollView.removeFromSuperview()
dismissViewControllerAnimated(true, completion: {})
}
I manually removed some views and contents. I've done it in "Back" button but you can do this in other methods like viewWillDisappear(animated: Bool).
Once I made this, my allocation chart in the developer instruments showed the memory allocation going up and down... And it was solved...
I think you get an error, when you try to pop the view controller because the navigation controller does not have a valid reference to the view controller, as it was released after you pushed it.
Nil the popover on dismiss.
[menuPopup_ dismissPopoverAnimated:YES];
menuPopup_ = nil;
Make sure your viewcontroller (A) has no reference of any other viewcontroller (B) or any object it has. Incase it has then make sure that VC-B is not referencing back VC-A. If it has some reference back to VC-A then make it a weak property. Otherwise strong retain cycle will keep the VC in memory even if its popped.
Another thing is to check wether theres any closure in your VC, check its body if it is referencing any property or method with self then make a Capture list to avoid retain cycle as "Closures are Reference Types"
Check if theres any NSNotification observer you are not releasing
Make a print call in deinit method to check wether its deallocated.
For further understanding on memory management:
https://medium.com/mackmobile/avoiding-retain-cycles-in-swift-7b08d50fe3ef
https://www.youtube.com/watch?v=GIy-qnGLpHU
You should use an unwind segue instead of popping.
my project use ARC, and when i have to show a view with navigation controller i do this:
ShareViewController_iPhone *share = [[ShareViewController_iPhone alloc] initWithNibName:#"ShareViewController_iPhone" bundle:nil];
[self.navigationController pushViewController:share animated:YES];
and i can see in xcode that the memory is increased of a certain value, then when i dismiss the view i do this:
[self.navigationController popViewControllerAnimated:YES];
but when the view is closed, the memory doesn't decrease, how i can do it?
When you pop the viewcontroller, it is marked for deallocation (i.e it's reference count becomes 0 unless referenced by another object). but not deallocated immediately. Deallocation as far I have seen is mostly random!
The view controller here must be retained for a while by the navigation controller itself to create the animation. The deallocation does happen immeadiately after the reference count drops to zero. Try to pop the view controller without animation (e.g. animated:NO) and see for yourself if the deallocation happens right away.
ARC will clean the memory on its own cycle (it will collect all the objects whose reference count set to "0" means who are ready for deallocation), we can't control this. It is managed by the operating system.
So when you are popping a view controller, it doesn't deallocate it from the memory immediately. It can take time depending on the other memory usage/memory availability.
One more case, you need to check if on every push the memory allocation is increased by a certain value, then there will be definitely something wrong in your code.
When you pop a ViewController and it don't release, it means have a reference cycle in your controller. You must check delegate if have, block, weak, strong reference.
Your delegate must be weak reference.
If use block. The self must be weak reference: __weak id weakSekf = self;
Hope these information will help you. :)
I have a stack of UIViewControllers currently, each is a modal ViewController presented over the previous one. My problem is that I do not need a stack of UIViewControllers, I only need the last one. So when a new UIViewControllersis presented, its parent should be purged, deleted completely from memory. My app will never need those viewcontrollers again.
I have read this: http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/ViewLoadingandUnloading/ViewLoadingandUnloading.html
But this pattern only cares with memory freeing if the app gets a memory warning. And doesn't purge viewcontrollers, only their content. I would like to do it in a more manual manner... Is this possible, or it is not a common practice in iOS, and I should rely only on memory warning messages.
The easiest way is to avoid creating the stack in the first place. Instead of presenting new modal controllers over existing ones, have your root controller dismiss the existing one first and present each new one.
I might have found a nice solution. One should use a UINavigationController, and manage its viewContollers property (which is the stack of UIViewControllers) manually. After (or before) the new UIViewController loaded, you can delete the old UIViewController from the stack, and thus purge it from the memory.
This post helped:
How can I pop a view from a UINavigationController and replace it with another in one operation?
This way you can make a program flow, where only when UIViewController is in the memory at a time, and you replace them when you need a new UIViewController.