Der Einfachheit halber verwende ich eine Hilfsklasse, die es ermöglicht, eine Warteanzeige anzuzeigen, ohne dass in jeder Ansicht eine Variable/Referenz benötigt wird. Die Klasse implementieren eine statische Methode publicSpeicherverlust mit in einer statischen Methode initialisiertem Objekt und Verwendung von NSNotificationCenter
static void ShowActivityIndicator(UIView view, bool animated, UIActivityIndicatorViewStyle style)
Bei dieser Methode Ich bin ein DFActivity Indikatoren erstellen und auf der im Parameter angegebenen Ansicht anzuzeigen:
DFActivityIndicator activityIndicator = new DFActivityIndicator(view.Bounds);
view.AddSubview(activityIndicator);
activityIndicator.LabelText = NSBundle.MainBundle.LocalizedString("Loading...", "");
activityIndicator.Indicator.ActivityIndicatorViewStyle = style;
activityIndicator.Show(true);
Der Konstruktor der Methode ist:
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);
}
Der Beobachter ist hier in der Lage, den Indikator zu drehen, wenn die Schnittstelle gedreht wird. Wenn der Indikator nicht mehr benötigt, ich habe eine andere statische Methode:
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;
}
}
Dies funktioniert gut, erwartet, dass die Mono-Profiler zeigen an, dass jedes Mal, wenn ich ShowActivityIndicator
nenne, jede Instanz in dem Speicher gehalten wird, selbst wenn ich Rufen Sie HideActivityIndicator
für alle Instanzen auf. Die Erinnerung an meine Anwendung steigt dann nur noch bis zum Absturz (scheint also ein Speicherleck zu sein). Zum Debuggen habe ich versucht, den Beobachter bei Orientierungsänderungen zu entfernen: NSNotificationCenter.DefaultCenter.AddObserver(UIApplication.DidChangeStatusBarOrientationNotification, DeviceOrientationDidChange, this)
) und ... der Code leckt nicht mehr. Ist es ein MonoTouch Bug oder mache ich etwas anderes falsch?
Meine Vermutung ist, ich nicht das Recht addObserver/removeObserver Methode verwende. – nicolas
Sie sagen also, dass das Entfernen des Beobachters in HideActivityIndicator nicht funktioniert, aber das Entfernen des Beobachters bei Orientierungsänderungen funktioniert? Der HeapShot-Profiler kann Ihnen auch mitteilen, welches Objekt den DFActivityIndicator am Leben erhält, wenn Sie das Kontrollkästchen "Inverse Referenzen" aktivieren. –
Nein, wenn ich die Zeilen 'AddObserver' und 'RemoveObserver' kommentiere, scheint es, dass es keine Lecks mehr gibt. Die Referenz, die 'DFActivityIndicator' am Leben zu halten scheint, ist' System.Action ', gehalten von' MonoTouch.Foundation.InternalNSNotificationHandler', gehalten von 'System.Collection.Generic.List ', gehalten von 'MonoTouch .Foundation.NSNotifikationszentrum'. –
nicolas