Tasharen Entertainment Forum

Support => NGUI 3 Support => Topic started by: Ferazel on September 29, 2014, 05:19:48 PM

Title: 3.7.4 iOS - "PropertyToID can only be called from the main thread" crash.
Post by: Ferazel on September 29, 2014, 05:19:48 PM
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.
Title: Re: 3.7.4 iOS - "PropertyToID can only be called from the main thread" crash.
Post by: ArenMook 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.         }
Title: Re: 3.7.4 iOS - "PropertyToID can only be called from the main thread" crash.
Post by: Ferazel 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.
Title: Re: 3.7.4 iOS - "PropertyToID can only be called from the main thread" crash.
Post by: yuewah on October 08, 2014, 09:53:38 PM
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 ?
Title: Re: 3.7.4 iOS - "PropertyToID can only be called from the main thread" crash.
Post by: ArenMook on October 10, 2014, 02:11:29 AM
Yup, already have on my end. It'll be like that in the next update.