gpt4 book ai didi

c# - 在静态方法中初始化对象并使用 NSNotificationCenter 的内存泄漏

转载 作者:行者123 更新时间:2023-12-01 19:21:52 28 4
gpt4 key购买 nike

为方便起见,我使用了一个帮助类,它允许显示等待指示器,而无需对每个 View 进行变量/引用。该类实现了一个静态方法public

static void ShowActivityIndicator(UIView view, bool animated,  UIActivityIndicatorViewStyle style)

在此方法中,我创建了一个 DFActivity 指标并将其显示在参数中给出的 View 上:
DFActivityIndicator activityIndicator = new DFActivityIndicator(view.Bounds);
view.AddSubview(activityIndicator);
activityIndicator.LabelText = NSBundle.MainBundle.LocalizedString("Loading...", "");
activityIndicator.Indicator.ActivityIndicatorViewStyle = style;
activityIndicator.Show(true);

该方法的构造函数是:
public DFActivityIndicator(RectangleF frame) : base(frame)
{

Indicator = new UIActivityIndicatorView(UIActivityIndicatorViewStyle.Gray);
this.AddSubview(Indicator);
Indicator.StartAnimating();
Indicator.Frame = new RectangleF(0.0f, 0.0f, 20.0f, 20.0f);
Indicator.StartAnimating();

//...

Label = new UILabel(Bounds);

RotationTransform = CGAffineTransform.MakeIdentity();
NSNotificationCenter.DefaultCenter.AddObserver(UIApplication.DidChangeStatusBarOrientationNotification, DeviceOrientationDidChange, this);

}

观察者在这里是为了能够在界面旋转时旋转指示器。当不再需要指标时,我有另一个静态方法:
 public static bool HideActivityIndicator(UIView view, bool animated)
{
UIView viewToRemove = null;
foreach(UIView v in view.Subviews)
{
if (v is DFActivityIndicator)
{
viewToRemove = v;
}
}

if (viewToRemove != null)
{
DFActivityIndicator activityIndicator = viewToRemove as DFActivityIndicator;
NSNotificationCenter.DefaultCenter.RemoveObserver(activityIndicator, UIApplication.DidChangeStatusBarOrientationNotification, null);
activityIndicator.RemoveFromSuperview();
activityIndicator.Dispose();
activityIndicator = null;
return true;
}
else
{
return false;
}
}

这工作正常,希望 Mono 分析器指示每次我调用 ShowActivityIndicator ,即使我调用 HideActivityIndicator,每个实例都会保存在内存中对于所有情况。然后我的应用程序的内存只会增加直到崩溃(因此似乎是内存泄漏)。为了调试,我尝试在方向更改时移除观察者: NSNotificationCenter.DefaultCenter.AddObserver(UIApplication.DidChangeStatusBarOrientationNotification, DeviceOrientationDidChange, this) )
并且...代码不再泄漏。是 MonoTouch 错误还是我做错了什么?

最佳答案

是的,我认为您没有正确使用 AddObsever/RemoveObserver 方法。

这是您对正在使用的重载所做的操作:

NSNotificationCenter.DefaultCenter.AddObserver(UIApplication.DidChangeStatusBarOrientationNotification, DeviceOrientationDidChange, this);

您正在注册接收状态栏方向更改的通知,这将触发 DeviceOrientationChange 回调, 如果这些通知来自 this .因此,您的回调将永远不会被触发(因为您的 DFActivityIndi​​cator 永远不会发布这样的通知)但是,默认中心(或者更好的是,您在评论中提到的一系列对象)将持有对 View 的引用。
NSNotificationCenter.DefaultCenter.RemoveObserver(activityIndicator, UIApplication.DidChangeStatusBarOrientationNotification, null);

您正在尝试删除 View 而不是通知观察者。其余参数无需解释。

这是你应该做的:
//To add the observer:
NSObject observerObject;
//..
this.observerObject = NSNotificationCenter.DefaultCenter.AddObserver(UIApplication.DidChangeStatusBarOrientationNotification, DeviceOrientationDidChange)
//..
//To remove the observer:
NSNotificationCenter.DefaultCenter.RemoveObserver(this.observerObject);

关于c# - 在静态方法中初始化对象并使用 NSNotificationCenter 的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9980402/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com