When generating an application, mtouch calls a tool called the linker, which is used to remove from the class libraries the features that the application is not using. This is done to reduce the size of the application, which will ship with only the necessary bits.
The linker uses static analysis to determine the different code paths that your application is susceptible to follow. It's a bit heavy as it has to go through every detail of each assembly, to make sure that nothing discoverable is removed.
As the linker is a static tool, it can not mark for inclusion types and methods that are called through reflection, or dynamically instantiated.
The linking process can be customized in three different ways. You can either chose to not link your application, to link the MonoTouch SDK assemblies only, leaving your assemblies untouched, or you can link every assembly.
You can tell mtouch to not link any assembly by specifying the -nolink switch. Not linking will make sure that no assemblies are modified. This should only be used as a workaround whenever the linker contains a bug that prevents your application to run. If your application only works with -nolink, please submit a bug.
This is the current default setting for projects created in MonoDevelop. It calls mtouch with the -linksdkonly flag. In this mode, the linker will leave your assemblies untouched, and will reduce the size of the SDK by removing everything that your application doesn't use.
This is the most simple option, as it does not require any change in your code. The difference with linking everything is that the linker can not perform a few optimizations in this mode, so it's a trade-off between the work needed to link everything and the final application size.
When linking everything, the linker can use the whole set of its optimizations to make the application as small as possible. It will modify user code, which may break whenever the code uses features sur as webservices, reflection, or serialization.
For instance, serialization requires that a type contains a default (parameter less) constructor. In this mode, if the constructor is not statically called by your code, the linker will remove the constructor. You can control this feature by putting a [Preserve] attribute on the member that you don't want to see removed, or you can put a [Preserve (AllMembers = true)] attribute on the type defining the member, to make sure everything is preserved.