Author Topic: 3.7.4 iOS - "PropertyToID can only be called from the main thread" crash.  (Read 4409 times)

Ferazel

  • Full Member
  • ***
  • Thank You
  • -Given: 1
  • -Receive: 2
  • Posts: 150
    • View Profile
We upgraded our project to NGUI 3.7.4 and we started experiencing some problems with an exception that is being thrown when in development build.

Unhandled Exception: System.ArgumentException: PropertyToID can only be called from the main thread.
Constructors and field initializers will be executed from the loading thread when loading a scene.
Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.

We believe that the problem is that on line 636 of UIDrawCall you create the references via

  1.        
  2. static int[] ClipRange =
  3.         {
  4.                 Shader.PropertyToID("_ClipRange0"),
  5.                 Shader.PropertyToID("_ClipRange1"),
  6.                 Shader.PropertyToID("_ClipRange2"),
  7.                 Shader.PropertyToID("_ClipRange4"),
  8.         };
  9.  
  10. static int[] ClipArgs =
  11.         {
  12.                 Shader.PropertyToID("_ClipArgs0"),
  13.                 Shader.PropertyToID("_ClipArgs1"),
  14.                 Shader.PropertyToID("_ClipArgs2"),
  15.                 Shader.PropertyToID("_ClipArgs3"),
  16.         };
  17.  

I think these arrays be created in the Awake() if possible and not as an initializers.

We were able to reproduce the crash in a naked project. Import NGUI. Set player settings to be FAST & NO Exceptions. In the build settings check for "Development build" and build onto the device. When the scene starts to load this exception will be thrown and crash the app.
NGUI 3.7.4 (Downloaded and upgraded on September 29th)
Unity 4.5.4f1
XCode 6.0.1
Multiple devices running both iOS 7 and iOS 8 exhibited this behavior.

Let me know if you need additional information.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: 3.7.4 iOS - "PropertyToID can only be called from the main thread" crash.
« Reply #1 on: September 30, 2014, 04:17:16 AM »
Why would this be accessed from a different thread? UIDrawCall is only accessed from the main thread.

As you mentioned you can work around it with initializing them in Awake, but that doesn't explain what this is caused by.
  1.         /// <summary>
  2.         /// Cache the property IDs.
  3.         /// </summary>
  4.  
  5.         void Awake ()
  6.         {
  7.                 if (ClipRange == null)
  8.                 {
  9.                         ClipRange = new int[]
  10.                         {
  11.                                 Shader.PropertyToID("_ClipRange0"),
  12.                                 Shader.PropertyToID("_ClipRange1"),
  13.                                 Shader.PropertyToID("_ClipRange2"),
  14.                                 Shader.PropertyToID("_ClipRange4"),
  15.                         };
  16.                 }
  17.  
  18.                 if (ClipArgs == null)
  19.                 {
  20.                         ClipArgs = new int[]
  21.                         {
  22.                                 Shader.PropertyToID("_ClipArgs0"),
  23.                                 Shader.PropertyToID("_ClipArgs1"),
  24.                                 Shader.PropertyToID("_ClipArgs2"),
  25.                                 Shader.PropertyToID("_ClipArgs3"),
  26.                         };
  27.                 }
  28.         }

Ferazel

  • Full Member
  • ***
  • Thank You
  • -Given: 1
  • -Receive: 2
  • Posts: 150
    • View Profile
Re: 3.7.4 iOS - "PropertyToID can only be called from the main thread" crash.
« Reply #2 on: September 30, 2014, 09:09:26 AM »
I assume it is being accessed from a different thread if the scene is scene id 0 (which unity streams the level load from what I understand). I was able to replicate this problem with the included examples. You need to turn off exception handling in the player settings and turn on the development build and build the scene as scene 0.

yuewah

  • Full Member
  • ***
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 180
    • View Profile
I also have the same problem, I guess it may be Unity3d bug. Can you update NGUI with the work around by initializing them in Awake ?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Yup, already have on my end. It'll be like that in the next update.