Unity什么是 Null 引用異常 (Null Reference Exception)?
嘗試訪問未引用任何對象的引用變量時,便發(fā)生?NullReferenceException
。如果引用變量未引用任何對象,則將其視為?null
。當變量為?null
?時,運行時將通過發(fā)出?NullReferenceException
?來告知正在嘗試訪問對象。
c# 和 JavaScript 中的引用變量在概念上類似于 C 和 C++ 中的指針。引用類型默認為?null
,表示未引用任何對象。因此,如果嘗試訪問被引用的對象而又沒有該對象,則將出現(xiàn)?NullReferenceException
。
當代碼中出現(xiàn)?NullReferenceException
?時,意味著在使用變量之前忘記設置該變量。錯誤消息將如下所示:
NullReferenceException: Object reference not set to an instance of an object ?at Example.Start () [0x0000b] in /Unity/projects/nre/Assets/Example.cs:10
此錯誤消息表明?NullReferenceException
?發(fā)生在腳本文件?Example.cs
?的第 10 行。此外,該消息還指出異常發(fā)生在?Start()
?函數(shù)內(nèi)。根據(jù)這些信息,比較容易查找和修復 Null 引用異常。在此示例中,代碼為:
//c# 示例
using UnityEngine;
using System.Collections;
public class Example : MonoBehaviour{
?// 使用此函數(shù)進行初始化
?void Start (){
? ?GameObject go = GameObject.Find("wibble");
? ?Debug.Log(go.name);
?}
}
該代碼簡單地查找一個名為“wibble”的游戲?qū)ο?。在此示例中不存在該名稱的游戲?qū)ο螅虼?Find()
?函數(shù)返回?null
。在下一行(第 9 行),我們使用?go
?變量并嘗試打印出其引用的游戲?qū)ο蟮拿Q。因為我們正在訪問一個不存在的游戲?qū)ο螅赃\行時拋出一個?NullReferenceException
Null 檢查
雖然發(fā)生這種情況時令人沮喪,但這只是意味著需要更加注意腳本。這個簡單示例中的解決方案是按如下所示的方式更改代碼:
using UnityEngine;
using System.Collections;
public class Example : MonoBehaviour{
?void Start () {
? ?GameObject go = GameObject.Find("wibble");
? ?if (go) {
? ? ?Debug.Log(go.name);
? ?}
? ?else{
? ? ?Debug.Log("No game object called wibble found");
? ?}
?}
}
現(xiàn)在,在我們嘗試對?go
?變量執(zhí)行任何操作之前,我們檢查它是不是?null
。如果是?null
,則顯示一條消息。
Try/Catch 代碼塊
出現(xiàn)?NullReferenceException
?的另一個原因是使用了應該在 Inspector 中初始化的變量。如果忘記這樣做,則變量將為?null
。處理?NullReferenceException
?的另一種方法是使用 try/catch 代碼塊。例如,以下代碼:
using UnityEngine;
using System;
using System.Collections;
public class Example2 : MonoBehaviour{
?public Light myLight;
?// 在 Inspector 中設置
?void Start (){
? ?try {
? ? ?myLight.color = Color.yellow;
? ?}
? ?catch (NullReferenceException ex){
? ? ?Debug.Log("myLight was not set in the inspector");
? ?}
?}
}
在此代碼示例中,名為?myLight
?的變量是應該在 Inspector 窗口中設置的?Light
。如果未設置此變量,則默認為?null
。嘗試在?try
?代碼塊中改變光源的顏色會導致被?catch
?代碼塊捕獲到的?NullReferenceException
。catch
?代碼塊將顯示一條消息,此消息可能對美術(shù)師和游戲設計師更有幫助,并提醒他們在 Inspector 中設置光源。
摘要 (Summary)
腳本代碼嘗試使用未設置(引用)的變量和對象時,便會發(fā)生?
NullReferenceException
。出現(xiàn)的錯誤消息可顯示有關(guān)在代碼中何處發(fā)生了問題的大量信息。
通過編寫代碼在訪問對象之前檢查?
null
?或使用 try/catch 代碼塊,可避免?NullReferenceException
。