Advertisement

Mind blow null object

Started by August 31, 2016 03:46 AM
5 comments, last by frob 8 years, 2 months ago
J1_Lt1e5.png
This blow my head off because I do not understand why I can access information in a null object, and because I don't not know what keyword to put in google to search so decide to ask here. thanks
And I just added these line below
if (currentSelectedCard [0] == null) {
Debug.Log("null");
}
and the console prints out null , How can I go around it in this case
Your link is broken, remove the trailing two characters.

Regarding the nulls, I'm not entirely sure, but my educated guess goes along this: With LinQs late evaluation you may run into situations where the debugger may not show the true story.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

Advertisement
Unity objects have two "sides" to them - the C# side and the internal C++ side. A normal C# object cannot be manually destroyed as long as there is any reference to it, and this is still true in Unity. Another way of saying this is that *nothing* can forcibly null out variables that you're using in your code, but Unity tries to make it LOOK like it.

However, the C++ side CAN be destroyed at almost any time. When this happens, Unity has overloaded some operators in the base class that causes comparisons with null to be "true" (even though the reference is not ACTUALLY null) to indicate this has happened. It also has a customization in place to print null in the debugger.

When a Unity component/object is in this state, you can safely access any pure C# members of that object, but you will get exceptions/errors if you try to access any of the Unity-specific stuff (like the transform, containing gameObject, etc). Note: This is NOT like dereferencing a deleted pointer in C++ that just happens to have the old data around still. The C# object is still completely alive.

In this case, you've got some Unity-derived object in your m_cardDB collection which has had its C++ "side" destroyed, but you've still got a reference to the C# "side" of it in your collection which allowed you to access the m_Number member.

The C++ side has things like the transform relationships, the gameObject reference, the set of components on the object, etc. Stuff which the Unity engine uses internally.

The C# side has everything that you've written in any of your own C# files, including classes derived from MonoBehaviour.


To solve your actual problem, you have a few options:

- When the object gets destroyed, handle OnDestroyed to remove that object from your other C# collections (by posting an event or something like that).
- Periodically check your collection for null entries whenever you need to, and voluntarily remove anything that's null.
- Perhaps there's a problem that's causing the object to be destroyed before you actually wanted it to be, and you can fix that.

So if I'm correct does that mean if this class/script never attach to any gameobject this will be always null ?

for example : List<SYC_BusinessDB> m_cardDB , and in my game I have create some objects of SYC_BusinessDB and put it in m_cardDB but however I have never any SYC_BusinessDB to any GameObject so because of that it destroy the c++ side is that correct ?

If you're using 'new SYC_BusinessDB' and SYC_BusinessDB is derived from MonoBehaviour, then Unity should be printing errors/warnings about that. I don't remember off the top of my head if improperly created MonoBehaviours start off "null" or not, but you might be right.

If your SYC_BusinessDB class doesn't ever need to be attached to a gameObject as a component, just don't derive from MonoBehaviour. You'll get a "POCO" - a "Plain Old C# Object". Those will work just like C# objects do in non-Unity projects and don't have any of the weird "pretends to be null" stuff.

If you DO need it to be attached to a gameObject as a component, then you'll need to properly instantiate it using one of Unity's methods, like GameObject.AddComponent<T>, instead of using 'new'.

For The Record -

I Have A Reference In My C# Script That Confuses Me Too
1. I'm Using "Object A" Transform To Move "Object B"

2. I Destroy "Object B" That's Referenced In That Class

3. I Then Pass A New Instance INTO THE DESTROYED "Object B" - Now It's "Object C"

ALL I KNOW IS IT WORKS.
AND I CAN'T EVEN EXPLAIN IT.

Advertisement

ALL I KNOW IS IT WORKS. AND I CAN'T EVEN EXPLAIN IT.

Post code, preferably to a new topic since this one is about an issue that is already discussed.

This topic is closed to new replies.

Advertisement