I have been using the method described here:
successfully for many months. Today, I started getting the following error when I try to write a file on the iPod:
ExecutionEngineException: Attempting to JIT compile method 'Serializer__TypeMetadata:.ctor ()' while running with --aot-only.
Any idea why this is happening? The call stack follows:
at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object parameters, System.Globalization.CultureInfo culture) [0x00000] in :0 Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation. at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object parameters, System.Globalization.CultureInfo culture) [0x00000] in :0 at System.Reflection.MonoCMethod.Invoke (BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object parameters, System.Globalization.CultureInfo culture) [0x00000] in :0 at System.Reflection.ConstructorInfo.Invoke (System.Object parameters) [0x00000] in :0 at System.Activator.CreateInstance (System.Type type, Boolean nonPublic) [0x00000] in :0 at System.Activator.CreateInstance (System.Type type) [0x00000] in :0 at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.CreateMemberTypeMetadata (System.Type type) [0x00000] in :0 at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.GetObjectData (System.Object obj, System.Runtime.Serialization.Formatters.Binary.TypeMetadata& metadata, System.Object& data) [0x00000] in :0 at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteObject (System.IO.BinaryWriter writer, Int64 id, System.Object obj) [0x00000] in :0 at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteObjectInstance (System.IO.BinaryWriter writer, System.Object obj, Boolean isValueObject) [0x00000] in :0 at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteQueuedObjects (System.IO.BinaryWriter writer) [0x00000] in :0 at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteObjectGraph (System.IO.BinaryWriter writer, System.Object obj, System.Runtime.Remoting.Messaging.Header headers) [0x00000] in :0 at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize (System.IO.Stream serializationStream, System.Object graph, System.Runtime.Remoting.Messaging.Header headers) [0x00000] in :0 at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize (System.IO.Stream serializationStream, System.Object graph) [0x00000] in :0 at QSerializer.WriteFile[Serializer] (System.String fileName, .Serializer source) [0x00000] in :0 at Player.Write () [0x00000] in :0 at G.Save () [0x00000] in :0 at G.OnLevelWasLoaded () [0x00000] in :0
Answer by Nico de Poel
Jul 24, 2013 at 03:44 PM
We had the same problem with a bit of code that uses a BinaryFormatter to (indirectly) serialize an enum value. The BinaryFormatter (or the ObjectWriter used by it to be more precise) attempts to create its own special brand of type metadata for the value, and for custom value types (like structs or enums defined in your code) it will try to dynamically generate a class for that metadata. Which fails on iOS since it does not support run-time code generation.
Using .NET Reflector, I took a look at the serializer code in question, and found out that the ObjectWriter can use a different code path that doesn't rely on run-time code generation, but on reflection instead. And the code path that it uses is configurable with an environment variable.
Just add the following line to the Awake() function of the MonoBehaviour script that uses the BinaryFormatter:
// Forces a different code path in the BinaryFormatter that doesn't rely on run-time code generation (which would break on iOS).
... and the BinaryFormatter should work fine on iOS. In theory, using reflection for type metadata will be a little bit slower than using a precompiled class, but in practice you probably won't notice any difference. And it's better than not working at all.
The SetEnvironmentVariable technique worked perfectly! Many thanks.
You are a star! this worked for me too and saved me a ton of effort having to convert everything over to some other kind of serialisation.
thanks! it even works for serialization of generic in generic collections
This should be the accepted answer. Thank you!
SetEnvironmentVariable worked for me when I had to call
System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo("xx-XX");
on iOS. Thanks!
Answer by r618
Nov 22, 2011 at 11:54 PM
not sure about this either Is there any kind of mono stripping involved ? If that doesn't help I'd file a bug report and/or implement ISerializer interface ( see e.g. http://forum.unity3d.com/threads/79138-I-love-strippers!-aka-Network-Errors-amp-Build-Stripping-question ) There are many problems/reports like this, I personally ended up using XMLSerializer for now since refactoring or providing custom serializer for all classes would be very tedious and I couldn't find the culprit causing JIT compiling *__TypeMetadata:.ctor () using BinaryFormatter
Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.
The best place to ask and answer questions about development with Unity.
To help users navigate the site we have posted a site navigation guide.
If you are a new user to Unity Answers, check out our FAQ for more information.
Make sure to check out our Knowledge Base for commonly asked Unity questions.
If you are a moderator, see our Moderator Guidelines page.
We are making improvements to UA, see the list of changes.
Answers and Comments
8 People are following this question.
Could not serialize text file - out of memory
Saving Data on IOS produces JIT Error in Xcode
How to use Reactive Extensions on iOS ?
Loading scripts dynamically in AoT compilers
Steps to determine cause of AOT Cross Compile Failed