Hello,
In app lifecycle events, low memory delegates have been implemented for Android but not iOS. You could create a feature request at https://github.com/dotnet/maui/issues/new/choose.
As described in Apple's responding to low-memory warnings doc, you could implement the applicationDidReceiveMemoryWarning(_:)
method of your app delegate and the didReceiveMemoryWarning()
method of active UIViewController
objects.
Please refer to the following code:
public class AppDelegate : MauiUIApplicationDelegate
{
[Export("applicationDidReceiveMemoryWarning:")]
public void ReceiveMemoryWarning(UIApplication application)
{
...}//receive
}
Each ContentPage
has a PageHandler, please refer to this solution and create a custom handler which inherit PageHandler, then override the DidReceiveMemoryWarning
method.
#if IOS
public class ReceiveMemoryPageHandler : PageHandler
{
class MyPageViewController : PageViewController
{
public MyPageViewController(IView page, IMauiContext mauiContext) : base(page, mauiContext)
{
}
public override void DidReceiveMemoryWarning()
{
base.DidReceiveMemoryWarning();
}
}
protected override Microsoft.Maui.Platform.ContentView CreatePlatformView()
{// refer to https://github.com/dotnet/maui/issues/7174#issuecomment-1505519377
}
#endif
Register ReceiveMemoryPageHandler
in MauiProgram.cs
:
#if IOS
builder.ConfigureMauiHandlers(handlers =>
{
handlers.AddHandler(typeof(MainPage), typeof(ReceiveMemoryPageHandler));
});
#endif
Update
Where should the "ReceiveMemoryWarning" method be placed? At the start of the existing "AppDelegate" class in AppDelegate.cs?
Yes. At the start of the existing "AppDelegate" class. (Platfoms/iOS/AppDelegate)
Where should the "ReceiveMemoryPageHandler" class be placed in the app?
ReceiveMemoryPageHandler
is a new class, you can put it at the end of MainPage.cs
or a new file in Platfoms/iOS
folder or other place, pay attention to the namespace and iOS condition(#if IOS ...#endif
).
Is "[Import(...)]" not required in this case?
Yes, because it's a native method. You could refer to the source code for other methods: MauiUIApplicationDelegate.cs
Where do I place the application code for reducing memory when the "applicationDidReceiveMemoryWarning" is issued by iOS?
It's depended on your needs. When you get the notification, you could deal with the business logic after base.DidReceiveMemoryWarning();
. I know you may be worried that the logic is not in this handler. You could try to publish message from this handler and subscribe to messages in the ViewModel. See Publish and subscribe to messages - .NET MAUI | Microsoft Learn
Update
What code should be placed in method ReceiveMemoryWarning?
The logic of cleaning the large resources, such as the item source of ListView, some image caches.
When does ReceiveMemoryWarning get called?
This notification usually is sent by operating system. You could simulate this process on your physical device by calling the following code:
#if IOS
UIKit.UIApplication.SharedApplication.PerformSelector(new ObjCRuntime.Selector("_performMemoryWarning"));
#endif
Or you could run the app on an iOS simulator, then go to Simulator->Debug->Simulate Memory Warning
Update
Would you mind clarifying what code should be placed in those two methods?
In UIKit.UIViewController.DidReceiveMemoryWarning method, what code should be placed depends on your app's logic. You could clean the large recourses. For example, I tried to clean the item source of a collectionview.(Refer to this official collectionview sample) clean item source in VM
public void CleanRecources()
{
Monkeys.Clear();
selectedMonkeys.Clear();
}
Find the handler in CollectionViewPage's loaded method (your MainPage)
private void CollectionViewPage_Loaded(object sender, EventArgs e)
{
#if IOS
ReceiveMemoryPageHandler handler = this.Handler as ReceiveMemoryPageHandler;
var myPageViewController = handler.ViewController as ReceiveMemoryPageHandler.MyPageViewController;
myPageViewController.LowMemoryAction += () =>
{
MonkeysViewModel vm = this.BindingContext as MonkeysViewModel;
vm.CleanRecources();
};
#endif
}
Add Action or MessageingCenter to invoke the cleaning recourses method.
public Action LowMemoryAction { get; set; }
public override void DidReceiveMemoryWarning()
{
base.DidReceiveMemoryWarning();
if (this.LowMemoryAction != null)
{
this.LowMemoryAction();//when you receive this DidReceiveMemoryWarning system notification, trigger the action to clean some large recourses.
}
// MessagingCenter.Send<MyPageViewController>(this, "lowmemory");
}
In applicationDidReceiveMemoryWarning
method, you could clean some global static recourses that store in your app.
Best Regards,
Wenyan Zhang
If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.