Ok I found the bug.
In NGUIText, lines 106 to 111 :
* The Update(bool request) method of NGUIText checks if dynamicFont is null
* If not, it requests some characters to help computing font's size
* This request sometimes triggers a font change, which calls UILabel's OnFontChanged callback where UIPanels get refreshed, which rebuilds every labels and clears the dynamicFont field (UILabel.cs, line 1751)
* just after that, NGUIText tries to get informations from ')' character from the dynamicFont which was not null... bam! it has indeed been nulled by the callback.
Here is the NRE stack trace :
NullReferenceException: Object reference not set to an instance of an object
NGUIText.Update (Boolean request) (at Assets/modules/ngui/src/Internal/NGUIText.cs:124)
NGUIText.Update () (at Assets/modules/ngui/src/Internal/NGUIText.cs:105)
UILabel.UpdateNGUIText () (at Assets/modules/ngui/src/UI/UILabel.cs:2046)
UILabel.ProcessText (Boolean legacyMode, Boolean full) (at Assets/modules/ngui/src/UI/UILabel.cs:1237)
UILabel.ProcessText () (at Assets/modules/ngui/src/UI/UILabel.cs:1197)
UILabel.ProcessAndRequest () (at Assets/modules/ngui/src/UI/UILabel.cs:1088)
UILabel.set_text (System.String value) (at Assets/modules/ngui/src/UI/UILabel.cs:280)
And here is the stacktrace of the call that clears dynamicFont field just before the NRE :
UILabel:OnFill(BetterList`1, BetterList`1, BetterList`1) (at Assets/modules/ngui/src/UI/UILabel.cs:1751)
UIWidget:UpdateGeometry(Int32) (at Assets/modules/ngui/src/Internal/UIWidget.cs:1461)
UIPanel:UpdateWidgets() (at Assets/modules/ngui/src/UI/UIPanel.cs:1596)
UIPanel:UpdateSelf() (at Assets/modules/ngui/src/UI/UIPanel.cs:1237)
UIPanel:LateUpdate() (at Assets/modules/ngui/src/UI/UIPanel.cs:1198)
UIPanel:Refresh() (at Assets/modules/ngui/src/UI/UIPanel.cs:1711)
UILabel:OnFontChanged(Font) (at Assets/modules/ngui/src/UI/UILabel.cs:1001)
UILabel:<SetActiveFont>m__2E() (at Assets/modules/ngui/src/UI/UILabel.cs:951)
UnityEngine.Font:RequestCharactersInTexture(String, Int32, FontStyle)
NGUIText:Update(Boolean) (at Assets/modules/ngui/src/Internal/NGUIText.cs:121)
NGUIText:Update() (at Assets/modules/ngui/src/Internal/NGUIText.cs:105)
UILabel:UpdateNGUIText() (at Assets/modules/ngui/src/UI/UILabel.cs:2046)
UILabel:ProcessText(Boolean, Boolean) (at Assets/modules/ngui/src/UI/UILabel.cs:1237)
UILabel:ProcessText() (at Assets/modules/ngui/src/UI/UILabel.cs:1197)
UILabel:ProcessAndRequest() (at Assets/modules/ngui/src/UI/UILabel.cs:1088)
UILabel:set_text(String) (at Assets/modules/ngui/src/UI/UILabel.cs:280)
One UGLY fix would be to insert
NGUIText.dynamicFont = font;
at the end of UILabel's OnFontChanged callback (line 1005), but this is dangerous since it could have a lot of side effects, just like the one that causes this bug. I think a better fix would be to make NGUIText be not static, immutable from outside, and instantiated when needed, instead of configured when needed then somewhat reset randomly.