Reputation: 1295
We are implementing an app which seems to have major memory leaks. For an example we have a view with its corrosponding viewmodel that is registered 38 times in the mono profiler but it should be garbage collected. We have a lot of custom controls etc. but where should these be disposed - as of ios 6 viewdidunload is not called anymore so where should we do our cleanup?
regards
Upvotes: 2
Views: 1561
Reputation: 32694
A good rule is that containees that are added to NSObject-based classes should only reference containers using WeakReference objects.
Like this:
// MyView is a UIView, which is an NSObject, so the rule will apply here
class MyView : UIView {
WeakReference<UIViewController> myController;
public MyView (RectangleF bounds, UIViewController myContainer)
: base (bounds) {
this.myController = myContainer;
}
}
Upvotes: 1
Reputation: 66882
This is a big question... and can't easily be answered for a general case.
In general, if you write nice simple ViewModels and nice simple Views, then you will not get any memory leaks.
However, if you have Views referencing ViewModels, which in turn have callbacks which somehow reference the Views, then it's very possible to get memory leaks - especially if your view models subscribe to events on services.
One particularly nasty situation is when ObjC and C# both have references to objects. There's some discussion of this on http://forums.xamarin.com/discussion/97/correct-way-to-pop-a-dialogviewcontroller-mine-are-staying-in-memory which also references a problem we once had in the SQL bits example - https://github.com/slodge/MvvmCross/issues/19
This may not be the case for your current leak, but it's worth reading Rolf's answer - http://forums.xamarin.com/discussion/comment/535/#Comment_535 - a few times - it's not an entry level explanation, but it makes sense eventually!
So, in order to tackle your current problem...
work out what is leaking
work out why - what is it that is holding on to the references.
fix it.
The key is to invest a decent amount of effort in doing the studying of 1 and 2, before diving in to the wrong fix for 3. There is no point in trying to 'fix it' without really knowing what 'it' is.
The good news is that the Mono profiler - with its built-in tooling to identify what has references to what - is really good for helping with this job.
From your description, I know you've already found this tool - but for anyone else reading, please see - http://docs.xamarin.com/ios/Guides/Deployment%252c_Testing%252c_and_Metrics/Monotouch_Profiler
Once, you've identified what is leaking and why, then step 3 will require some thinking, but will hopefully be easy to answer.
Sometimes the solution is to:
WeakReference
class to avoid leaks.Whatever happens, don't panic and do tackle this from an engineering perspective. These leaks happen in non-MvvmCross and non-MonoTouch code too - and using MvvmCross with a nice clean IoC architecture should make them easier to find and remove.
If the problem does turn out to be in an MvvmCross binding somewhere, then please do log it as a bug - I take these issues very seriously!
There is still an open bug in a long discussion on the MvvmCross repo about whether we shouldn't use WeakReferences for all our binding code - see https://github.com/slodge/MvvmCross/issues/17 - I've considered doing this - it would help people avoid some bugs... but not all. That issue is still open.
Update: I didn't answer
We have a lot of custom controls etc. but where should these be disposed
The framework should dispose these for you.
If it doesn't then that's probably because something else is leaking and holding on to your View which is then holding on to your Controls. You need to fix that underlying problem, rather than prematurely calling Dispose() on the Controls. Memory leak debugging isn't easy, but is kind of fun (sometimes)
Upvotes: 5