C#的null与Unity3d

说明:自己以后遇到的null问题都贴在这里。

原文链接:http://blog.csdn.net/a237653639/article/details/50676655

using System;

namespace ConsoleApplication1 {
    class Program {
        static void Main( string[] args ) {
            //测试一个引用设为null后,它所包含的字段是否也为null
            Person person3 = new Person();
            Children children1 = person3.MyChildren;
            person3 = null;
            Console.WriteLine( children1 == null );//false
            Console.ReadKey();            
        }
    }

    public class Person {
        public string Name { get; set; }
        public int Age { get; set; }
        public Children MyChildren { get; set; }
        public Person() {
            MyChildren = new Children();
        }
    }

    public class Children {
        public int BoyNum { get; set; }
        public int GirlNum { get; set; }
    }
}

以上代码中的chidren1并不为null。我们可以从堆栈和托管堆思考,person3置为了null,说明new Person()在托管堆中将被GC(其中所有的堆栈变量),但是之前person3的MyChildren所指向的对象还被引用着的,而GC的必要条件是回收没有任何指向该对象的内存,所以就不会GC MyChildren所指向的对象,自然children1就不为null了。也说明person3中的MyChildren也只是4个字节的引用而已,Children对象的创建(new Children())还是在托管堆上。所以Unity中的Destroy并不意味着将这个GameObject或者Component就真的彻彻底底地销毁了,只要你的代码中还引用着其中的某个对象,那么被引用的对象就还在托管堆上,一直存在着。所以要避免再次进入场景时还引用着之前创建的对象。


有两种方案来解决,

1.在OnDestroy或OnDisable等函数中置某些引用为null,以释放无用的对象和为下次OnEnable作准备,但是该类(脚本)本身并不会被释放。

2.保证你Destroy某GameObject的同时结束所有引用到 该GameObject及其所new出来的对象 的脚本的生命周期。而结束一个脚本的生命周期只有移除该脚本或者Destroy该脚本所依附的GameObject。如果只设该脚本的enable为false,该脚本的成员的引用不会变,不会变为null,所以设enable为false是不行的。


那么为什么必须要移除该脚本或Destroy该脚本所依附的GameObject才能彻底销毁呢?

1.这两种销毁方法使毫无疑问的,那么我们从“未能彻底销毁”这个角度来谈。 从.net 的角度出发,脚本还是一个类,它继承自MonoBehavior,由Unity替我们new这个对象(类),那么只要所依附的GameObject一直存在,这个GameObject上的脚本组件就一直被这个GameObject引用着,不会被释放,而所谓的enable也只是用于控制继承自MonoBehavior的函数的回调,就类这个角度而言,这个类的成员还一直保存着的。这也是为什么我们设置enable为false但是还是可以引用这个脚本及其成员的原因了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值