BinaryFormatter on iOS

If you’re trying to use a BinaryFormatter under iOS you may discover that it doesn’t work. You may get exceptions like “ExecutionEngineException: Attempting to JIT compile method ..”. This is because by default the mono BinaryFormatter uses runtime generated class serializers. This won’t work on iOS because JIT compilation is not permitted. To get around this, you can force mono to use reflection to perform the serialization instead. You can do this by inserting this line:

Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes");

somewhere in your project (e.g. in the Awake() method of the MonoBehaviour that needs to use serialization).

You could also instead use protobuf-net, which is a serializer for .NET that uses Google’s Protocol Buffers.

4 Responses to “BinaryFormatter on iOS”

  1. Yuriy on Reply

    Hi. Using this tip helped me serialize all my objects on a Ios device. But recently I had to add a Dictionary data structure to my project. It is the flowing: Dictionary<string, List>. This does not serialize on Ios and fires a JIT exception. Why is this happening and how can I get around it ?

  2. Sam on Reply

    I’m not exactly sure. There’s evidently some other part of Mono that is trying to generate code to perform the serialisation. Are you getting the “Attempting to JIT compile method” exception? What types are you storing in your List in the Dictionary?

    • Yuriy on Reply

      Hi, and thank you for a response. The type I’m storing in the List is from a class I made. The dictionary definition looks like this : Dictionary<string, List>, where Upgrade data is :
      [Serializable]
      public class UpgradeData
      {
      public bool lockStatus;
      public bool purchased;

      }
      and then the class that handles the Dictionary looks like this:
      [Serializable]
      public class CharacterUpgradeList
      {

      private UpgradeData[] _upgrade_Data;
      private List[] upgData;

      public Dictionary<string, List> upgradeList;
      public CharacterUpgradeList()
      {
      upgData = new List[4];
      for (int i = 0; i < upgData.Length; i++)
      {
      upgData[i] = new List {
      new UpgradeData(),
      new UpgradeData(),
      new UpgradeData(),
      new UpgradeData(),
      new UpgradeData(),
      new UpgradeData()
      };
      }

      upgradeList = new Dictionary<string, List>
      {
      {“Man”,upgData[0]},
      {“Woman”,upgData[1]},
      {“Boy”,upgData[2]},
      {“Girl”,upgData[3]}

      };
      }
      }

      • Sam on Reply

        I looked into this a bit. The BinaryFormatter (and other serialisers too, I assume) ends up calling an internal method in Generic.Dictionary called Do_CopyTo. It seems that for some reason Mono isn’t able to generate the code for this method ahead-of-time, so instead it tries to generate it at runtime. Looking at Do_CopyTo, I can’t see what would be confusing it. There’s a delegate argument, but it has all the type information so in theory it should have everything it needs. I tried forcing the compiler to generate a concrete class to work around it but I just couldn’t get it to generate it.

        To work around this you can use the Collections.Hashtable instead of the generic dictionary. It’s not as nice since it isn’t type safe and you have to cast everywhere, but at least it works.

        I thought the issue might have been the nested generics, but replacing the List<> with an ArrayList doesn’t help.

Leave a Reply to Yuriy

  • (will not be published)

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Current day month ye@r *