Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Change Button spriteState iOS exception \ bug

Discussion in 'UGUI & TextMesh Pro' started by Yaroslav1988, Feb 3, 2017.

  1. Yaroslav1988

    Yaroslav1988

    Joined:
    Oct 6, 2015
    Posts:
    13
    Hello!

    I found a bug in unity which appears when you try to change Button's spriteState and set pressedSprite field programmatically.

    The code below:

    Code (CSharp):
    1.  
    2.  
    3.     public Button btn;
    4.     public Sprite imgPress;
    5.  
    6.     // Use this for initialization
    7.     void Start () {
    8.         SpriteState ss = btn.spriteState;
    9.         ss.pressedSprite = imgPress;
    10.         btn.spriteState = ss;
    11.     }
    12.  
    13.  
    causes an exception TypeInitializationException with 100% possibility on iOS (ver. 8.4.1, iPad2 64GB).

    Works fine in editor though.

    Did anybody face same problem ? Is there any known solution ? Should i report a bug to support?

    Basically you just cant set pressed sprite from code if you using this:
    Unity 5.5.0f3
    all settings default except scripting backend - mono2x (only because it builds faster for test purposes)
    test devices: iPad2 64GB or iPad mini 16GB
    iOS: 8.4.1 or 10.0.2

    Thanks!

    Update1:
    there is no such exception if you use scripting backend - IL2CPP and Universal architecture, but its building sooooo long, you cant use it for testing in daily work, right ?

    PS

    zip with reproduce project in uploaded file
    full exception stacktrace:

    Code (CSharp):
    1. ExecutionEngineException: Attempting to JIT compile method 'System.Collections.Generic.GenericEqualityComparer`1<UnityEngine.UI.SpriteState>:.ctor ()' while running with --aot-only.
    2.  
    3.   at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
    4. Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
    5.   at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
    6.   at System.Reflection.MonoCMethod.Invoke (BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
    7.   at System.Reflection.ConstructorInfo.Invoke (System.Object[] parameters) [0x00000] in <filename unknown>:0
    8.   at System.Activator.CreateInstance (System.Type type, Boolean nonPublic) [0x00000] in <filename unknown>:0
    9.   at System.Activator.CreateInstance (System.Type type) [0x00000] in <filename unknown>:0
    10.   at System.Collections.Generic.EqualityComparer`1[UnityEngine.UI.SpriteState]..cctor () [0x00000] in <filename unknown>:0
    11. Rethrow as TypeInitializationException: An exception was thrown by the type initializer for System.Collections.Generic.EqualityComparer`1
    12.   at UnityEngine.UI.SetPropertyUtility.SetStruct[SpriteState] (UnityEngine.UI.SpriteState& currentValue, SpriteState newValue) [0x00000] in <filename unknown>:0
    13.   at UnityEngine.UI.Selectable.set_spriteState (SpriteState value) [0x00000] in <filename unknown>:0
    14.   at TestBtn.Start () [0x00000] in <filename unknown>:0
    15. (Filename:  Line: -1)
    16.  
    17. -> applicationWillResignActive()
    18. -> applicationDidEnterBackground()
    19.  
     

    Attached Files:

    Last edited: Feb 3, 2017
  2. juan-uran

    juan-uran

    Unity Technologies

    Joined:
    Dec 21, 2015
    Posts:
    2
    Hi!

    This is a change introduced to fix a boxing problem in SetPropertyUtility class. The function SetStruct uses currentValue.Equals(newValue) which will case the two values into objects to call equals. This will cause a memory allocation every time code sets a value. So, to fix that we change that call by
    EqualityComparer<T>.Default.Equals, which is now resulting in the JIT problem.

    Now, like a workaround, as the UI Framework is Open Source, you can open the file SetPropertyUtility.cs and change the if line using "EqualityComparer...." to "currentValue.Equals(newValue)". This will introduce the boxing problem again, but you will be able to use the Mono + iOS workflow on your end while we fix both problems in our code.

    We have a bug report created for these issues and will get a fix as soon as possible.

    Best regards,

    JD.
     
  3. zlSimon

    zlSimon

    Joined:
    Apr 11, 2013
    Posts:
    31
    Hi,
    I have the exact same problem however I cannot find SetPropertyUtility.cs. There is only a static class TMPro.SetPropertyUtility which uses currentValue.Equals(newValue).
    I do not understand why I get
    Code (CSharp):
    1. Rethrow as TypeInitializationException: An exception was thrown by the type initializer for System.Collections.Generic.EqualityComparer`1
    2.   at UnityEngine.UI.SetPropertyUtility.SetStruct[SpriteState] (UnityEngine.UI.SpriteState& currentValue, SpriteState newValue) [0x00000] in <filename unknown>:0
    There is no UnityEngine.UI.SetPropertyUtility.