内存泄漏,对象在静态方法中初始化,并使用NSNotificationCenter
本文关键字:初始化 NSNotificationCenter 静态方法 泄漏 对象 内存 | 更新日期: 2023-09-27 18:29:50
为了方便起见,我使用了一个助手类,它允许显示等待指示符,而不需要对每个视图进行变量/引用。该类实现了一个静态方法public
static void ShowActivityIndicator(UIView view, bool animated, UIActivityIndicatorViewStyle style)
在这种方法中,我创建了一个DFActivity指示器,并将其显示在参数中给出的视图上
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错误还是我做错了什么?
以下是您对正在使用的过载所做的操作:
NSNotificationCenter.DefaultCenter.AddObserver(UIApplication.DidChangeStatusBarOrientationNotification, DeviceOrientationDidChange, this);
您正在注册以接收状态栏方向更改的通知,如果这些通知来自this
,则会触发DeviceOrientationChange回调。因此,您的回调永远不会被触发(因为您的DFActivityIndicator从未发布过这样的通知),但默认的中心(或者更好的是,您在注释中提到的一系列对象)将包含对视图的引用。
NSNotificationCenter.DefaultCenter.RemoveObserver(activityIndicator, UIApplication.DidChangeStatusBarOrientationNotification, null);
您正试图删除一个视图,而不是一个通知观察器。无需解释其余参数。
以下是您应该做的:
//To add the observer:
NSObject observerObject;
//..
this.observerObject = NSNotificationCenter.DefaultCenter.AddObserver(UIApplication.DidChangeStatusBarOrientationNotification, DeviceOrientationDidChange)
//..
//To remove the observer:
NSNotificationCenter.DefaultCenter.RemoveObserver(this.observerObject);