3

Reading MT documentation, I've seen that it is possible to release memory also implementing the IDisposable .NET pattern.

For example, in a custom class that extends UIViewController (MyViewController), I could override the following method:

public override void Dispose (bool disposing)
{
   if (disposing){
     // do some stuff here
   }
   base.Dispose (disposing)
}

Starting from this point, my two questions are:

  1. What type of elements do I have to release in addition to images?
  2. Do I have to call the Dispose method from an instance of MyViewController class (myViewController.Dispose()) or the Dispose method is called automatically like dealloc method?

Thank you in advance. Regards.

poupou
  • 43,413
  • 6
  • 77
  • 174
Lorenzo B
  • 33,216
  • 24
  • 116
  • 190

1 Answers1

3

First MonoTouch usage of IDisposable is identical to Mono or .NET. What you read about this subject elsewhere, on stackoverflow or on MSDN... will all apply here.

What's important wrt MonoTouch is to remember that NSObject implements IDisposable which makes a lot of sense since it represent a native object. That means that everything that inherits from NSObject, quite a large part of monotouch.dll, implements IDisposable.

  1. What type of elements do I have to release in addition to images?

Most managed NSObject-based object instances are small but they can represent large native objects (the GC will only know about the first, managed, size).

So it's best to Dispose NSObject-based instances when you can, e.g. when you're using them as local variables. The using pattern makes it easy to do so in C#.

OTOH use your judgment, a small NSString won't take much memory, while others could be large (or unknown, e.g. NSString GetWebPageContent (NSUrl).

  1. Do I have to call the Dispose method from an instance of MyViewController class (myViewController.Dispose()) or the Dispose method is called automatically like dealloc method?

Part of the Dispose pattern ensure that the finalizer will call Dispose if it has not been called previously. As such the GC will, eventually, reclaim the memory (both managed and unmanaged/native) associated with those instances.

You might want to use some tools, like Gendarme (which will run on OSX) or FxCop (Windows-only) that will report to you (for example) if some of your types have IDisposable fields that are not disposed properly.

Disclaimer : I'm Gendarme's maintainer :-)

Community
  • 1
  • 1
poupou
  • 43,413
  • 6
  • 77
  • 174
  • Thank you for your reply. Very helpful. The only thing I didn't understand is the following: "Most managed NSObject-based object instances are small but they can represent large native objects (the GC will only know about the first, managed, size)." Could you explain what does it mean? Thank you again. – Lorenzo B Oct 08 '11 at 14:44
  • From _StackOverflow iDisposable Tag info_ it's clear the difference between managed and unmanaged objects: unmanaged ones are outside of the reach of the .NET garbage collector. In MT I haven't so clear the difference between the two and I have difficulties to apply the correct memory management behaviour. – Lorenzo B Oct 08 '11 at 14:51
  • 1
    Things like `new NSString ("a")` and `new NSString ("aaa...1000...aaa")` are, from a managed point of view, the same size - i.e. the sizeof(NSString) which is mostly just an handle, `IntPtr` that points to the native NSString object. As such the GC cannot use the *real* memory total to decide when to collect. However once the second is collected, `Dispose` will be called, and the long string will be freed. That's where some judgment when using (or not) `Dispose` inside your code can help you conserve memory (by ensuring it's released as-soon-as-possible). – poupou Oct 08 '11 at 14:56
  • That means I should use using() if dealing with NS* objects directly. But does this also apply if I use a managed Monotouch object that internally uses NS*? – Krumelur Oct 09 '11 at 10:57
  • A large part of monotouch.dll is generated by tools (btouch) and this ensure that Dispose is called when required (i.e. you don't have to worry about the internals of MonoTouch). However if an object contain `IDisposable` fields then it's a great *candidate* to implement `IDisposable` itself (Gendarme warns for this too). Judgment about when and how those types are used also applies (about implementing `IDisposable` and disposing manually the instances) - but it's never a *mistake* to do it (as long as th object is not required anymore, anywhere!) – poupou Oct 09 '11 at 14:04