What is the difference between applicationDidReceiveMemoryWarning , didReceiveMemoryWarning? - ios

What is the difference between applicationDidReceiveMemoryWarning and didReceiveMemoryWarning? What is the best way to handle those warnings?

You should be using "Lazy loading" of data on all your views.
For example, if you are displaying a list of data on a table view, you should release the data when your view controller receives a didReceiveMemoryWarning and set the data pointer to nil.
Most of the Apple sample code emphasizes on this lazy loading technique.
applicationDidReceiveMemoryWarning is a similar message sent to your AppDelegate. You should release unwanted global data that you store in your AppDelegate.
A classic example is Safari. Open say 2-3 tabs in Safari (on iPhone Simulator). Let all the tabs load the web page content. Try switching between different tabs. You should notice that the content remains there and is not flushed. Now from the menu, close "Simulate Memory Warning". Now when you switch to a different tab, Safari will fetch the contents again. Internally what has happened is that, the URL is remembered, but the entire web page contents was released in the didReceiveMemoryWarning method.
You should also implement similar mechanisms in your app.

Related

Is it recommended to destroy UIViewController after finishing your work with them

I'm an Android developer, I started learning iOS development lately and I've been wondering about how to manage the UIViewControllers.
In Android, when you don't need an activity anymore, it is better to remove it from the application stack, for example a login screen is only needed when the user logs in, after that there is no need for that screen so it is better to destroy it and remove it from the stack, but what about iOS? Do you have to manage view controllers the same way as activities? or does the system automatically handle the views in the background?
It would be great if you can link some reference to read more about the way View-controllers are handled in the background, I'm trying to learn the best practices
Short answer: No, let ARC handle it
ARC handles the release from memory automatically when you pop a view from a navigation stack, so if you go "back" (pop) you normally don't need to worry about it.
But, sometimes you have a big navigation stacks with many different views with a lot of data/images/etc that will eat memory. In those cases you could separate your app into different flows and instead replace the root view controller of the main window with the new flow every time you want to change. The old flow should be released from memory automatically, unless its connected to another object (like a singleton).

UWP memory leak using webview in MVVMCross application

I have a MVVMCross UWP application.
The first views are not remarkable until the user comes to a welcome page and from there goes to a dashboard.
Here lies a problem, somewhere is a memory leak and I can't find it.
The graphic shows memory usage in MB and navigations from welcome->dashboard and back.
The first section is navigating to a dashboard without an embedded webview, the second section has a webview element which loads a rather complex page with embedded video.
Some notes:
The webview, when enabled is loaded in code behind using the SeperateThread flag and set as the content of a ContentControl
On unloading the view I explicitly set the content of the ContentControl back to null, the temp value to null that holds the webview and manually call GC.Collect. If I do not do this the webview will continue playing the video in the background until the GC kicks in
I use a custom presenter (adding support for popups and to implement and call IDispoable/Dispose for my viewmodels (to not wait for the GC to clear subscriptions and such)
When analyzing memory dumps I can not see any changes in managed objects or memory
There seems to be a problem (a small leak) when not using the webview and I will look into this as well, right now I am more concerned about the second scenario
Where should I continue to ivestigate what is going on?
Thank you!
memory over several hours
EDIT:
Test Application available (see comments)
Just let it run for about 30 minutes to see the problem. Memory will steadily increase slightly until the application crashes (might take a few hours).
I kinda messed up the display and % for the memory usage. just watch application memory in task manager or export a csv file with the raw data
Same progression in sample app

Complex Startup Logic in iOS Apps: Where Should it Reside?

Everyone has seen the classic didFinishLaunchingMethod run amok.
Well now that we have additional things to consult when starting up like CloudKit, that are, to make things worse, asynchronous, the app delegate seems like the wrong place to do even the most basic stuff like asking if they have accounts and establishing syncing, or grabbing a snapshot.
I hate the idea that those things would go into the first controller that the app would launch, flashes me back to 4GL tinkertoys from days of yore.
Yet, we have to honor the flows of the storyboards. I have found nothing searching around on this. And sadly the most extensive Apple example, Lister, is not a great source for best practices.
It's suitable for the app delegate to trigger the start of this work, but not to handle the results. Often you want some way to display progress / errors / request user info. So, having some form of 'splash' view controller which handles the transition from your launch image into this process and controls the flow into the main app is handy. Generally the logic for this kind of thing is reusable in other situations so that part should be in some other controller class. The storyboard can make the splash VC the initial controller and the app delegate can create and pass it the data controller class which deals with the logic and updates the VC (it's delegate) with the results. Often the splash VC will then pass the data controller on to the subsequent VC it displays, though that isn't required of course.

can my app delegate be used as a controller of UIViewControllers (MVC)

Can an app delegate act the as the glue between all my UIViewControllers for the whole app?
I'm creating a mail client that has a navigation structure very much like sparrow (and fb etc). The first screen would be a login screen.. which would then lead to a UITableViewController that has the famous left menu button, which if clicked reveales other VC's underneath.
To make a long story short, right now it's my app delegate that's running the show.. it's the one that decides if to show the login screen if on first visit, or the default mailbox along with its subviews. If I get information from one subview, it hands off that info to the app delegate, which in turn passes it on to other view controllers.
Is this right from an MVC point of view? I know an app delegate is the first point of contact, it's what kicks off the application, but I haven't seen it used this extensively. I just want to make sure if I'm following iOS MVC best practices here.
It's not recommended, but it's perfectly legal to do that. I generally use a master view controller class and do most of the heavy lifting in that. Keep in mind that XCode will dump most of the auto generated code in the app delegate if you are using Core Data, so it can get a little difficult to navigate if you are using Core Data. It's really just a personal preference though. If it were me, I would still have the app delegate do the login screen vs. main screen logic, but put most of the app logic in a main screen controller.

How do I diagnose blocking in an iOS app?

So, I've got an iOS app which works nicely - usually, except the UI occasionally blocks. Is there a standard technique for diagnosing sporadically unresponsive UI?
In my case, I've got LRResty pulling data asynchronously, and the resultant data is parsed by NSXMLParser into some NSMutableArray objects.
I'd pin it on the XML parsing, but the UI doesn't block consistently in place. It blocks primarily after tapping the back button on my UINavigationBar, but also the initial table view doesn't scroll until the search bar is interacted with. Could there be a parser still working, or a request still working?
I use "Time Profiler" in instruments to see which methods are causing the unresponsive UI
(source: bmxmdb.com)
.
I just run it without touching anything, do the action in the app that you need to test, then stop recording, and after a lot of drilling down you find the offending method(s) this is my app accessing the DB.

Resources