Bug 23 - System.MissingMethodException: No constructor found for MonoTouch.AVFoundation.InternalAVAudioPlayerDelegate::.ctor(System.IntPtr)
Summary: System.MissingMethodException: No constructor found for MonoTouch.AVFoundatio...
Alias: None
Product: iOS
Classification: Xamarin
Component: Xamarin.iOS.dll ()
Version: 4.x
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Chris Toshok
Depends on:
Reported: 2011-07-20 03:57 UTC by ml+mt
Modified: 2011-07-25 21:23 UTC (History)
3 users (show)

Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description ml+mt 2011-07-20 03:57:03 UTC
In a ViewController I call the following code in ViewDidLoad(): 

AudioSession.Category = AudioSessionCategory.MediaPlayback; 

Then in response to some button presses I do: 

NSError err; 
var ap = AVAudioPlayer.FromUrl(new NSUrl("mysound.caf"), out err); 
ap.FinishedPlaying += delegate { ap.Dispose(); }; 

And this works great, pretty responsive etc. 

Except sometimes, seemingly randomly, I get the following unhandled 
exception in release mode on the device (iPhone 3GS): 

System.MissingMethodException: No constructor found for 

 at System.Activator.CreateInstance (System.Type type, BindingFlags 
bindingAttr, System.Reflection.Binder binder, System.Object[] args, 
System.Globalization.CultureInfo culture, System.Object[] 
activationAttributes) [0x000f1] in 
  at System.Activator.CreateInstance (System.Type type, 
System.Object[] args, System.Object[] activationAttributes) [0x00000] 
in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/Activator.cs:234
  at System.Activator.CreateInstance (System.Type type, 
System.Object[] args) [0x00000] in 
  at MonoTouch.ObjCRuntime.Runtime.ConstructNSObject (IntPtr ptr, 
IntPtr klass) [0x0000d] in 
  at MonoTouch.ObjCRuntime.Runtime.GetNSObject (IntPtr ptr) [0x0001f] 
in /Users/plasma/Source/iphone/monotouch/ObjCRuntime/Runtime.cs:197 
  at MonoTouch.ObjCRuntime.Runtime.GetNSObjectWrapped (IntPtr ptr) 
[0x00000] in /Users/plasma/Source/iphone/monotouch/ObjCRuntime/Runtime.cs:214 
  at (wrapper native-to-managed) 
MonoTouch.ObjCRuntime.Runtime:GetNSObjectWrapped (intptr) 
  at (wrapper managed-to-native) 
  at MonoTouch.UIKit.UIApplication.Main (System.String[] args, 
System.String principalClassName, System.String delegateClassName) 
[0x00038] in /Users/plasma/Source/iphone/monotouch/UIKit/UIApplication.cs:26 
  at MonoTouch.UIKit.UIApplication.Main (System.String[] args) 
[0x00000] in /Users/plasma/Source/iphone/monotouch/UIKit/UIApplication.cs:31 
  at MyNamespace.Application.Main (System.String[] args) [0x00016] in 

The AudioSession code is required to get volume control working. 
Without that, my volume buttons change the ringer volume, not the 
media volume. 

I have to call AudioSession.SetActive(true); every time I create an 
AVAudioPlayer, otherwise I risk an AudioSessionException with message 
"Application Audio Session is not active". 

I removed the anonymous method from FinishedPlaying, and instead do 
the following. 

I have a class-scoped List<AVAudioPlayer> called toDispose. 

On button press: 

    // call Play on a freshly instantiated AVAudioPlayer ap: 
    var ap = AVAudioPlayer.FromUrl(url, out err); 

    // next I check to see if toDispose has a bunch of AVAudioPlayers 
piled up, and if so, dispose all but the last couple in the list (my 
samples are only 0.15 seconds long so it's unlikely I'll dispose one 
that's currently playing this way) 
    // code snipped for brevity 

    // add the current AVAudioPlayer to the list of players to keep track of 

then finally in ViewWillDisappear() I dispose any remaining 
AVAudioPlayers in toDispose, and remove the disposed player from the 

Horrible but stable with many short samples being played, unlike the 
sample code on the MonoTouch website. 

See the following URL for discussion:

Comment 1 Miguel de Icaza [MSFT] 2011-07-22 12:15:20 UTC
Would you mind providing us with a self-contained test case?

We have a few theories as to what it could be, but we need the actual sample that is crashing to fix it.
Comment 2 Chris Toshok 2011-07-25 21:23:39 UTC
So, we've been doing a lot of thinking and hacking around the issue, and the only workable solution we can come up with at this point is (unfortunately) "don't do that."

You'll need to keep a strong ref to the player around or else both managed objects (the AVAudioPlayer and the InternalAVAudioPlayerDelegate) are free to be collected by the GC.  The reason it's not 100% reproducible is just an example of how it's difficult to reason about timing of code execution and object lifetimes when a GC is involved.

you can maybe make your toDispose solution a little more exact by using player.IsPlaying.

  var ap = AVAudioPlayer.FromUrl (...);

  ap.Finished += delegate {
    if (we haven't registered a callback to clear up the list) {
      use NSObject.PerformSelector to register Register_FlushList();

  ap.Play ();
  toDispose.Add (ap);

  void FlushList () {
    here you iterate over toDispose, removing/disposing players that have IsPlaying = false

I say "maybe" above because I'm not sure offhand if IsPlaying is set to true immediately upon calling ap.Play().  Also this presumably won't work if you're using ap.PlayAtTime.

We have made the exception message a little better in this situation - it will show the following now:

System.Exception: Selector invoked from objective-c on a managed object that has been GC'ed ---> System.MissingMethodException: No constructor found for MonoTouch.AVFoundation.InternalAVAudioPlayerDelegate::.ctor(System.IntPtr)