在进行项目的过程中,一直存在着对代码管理不当的问题,所以需要学习一些科学的代码思维,减少后期功能的修改与迭代引发的代码冗杂和内存爆炸
可以看b站这个大神的视频,讲的可以说无敌详细了,详细到萌新第一次接触会被劝退的地步(可能只是对我)
委托
含义
根据我观看视频和实际手操后,感觉和java里的接口有点类似,就是这个委托他啥也不干,就是一个指明方向的东东,也有点像指针(没接触过,但是有了解过),感觉就是通过他去找到另一个东东,然后调用他的方法。这么做的好处就是减少代码量,也可以提高代码的可读性和复用性。像java的接口就是只定义方法名,然后剩下的就是去实现这个接口,并且重写他。大概意思好像就是这样,看上面这个大佬的视频他在讲解的时候翻看官方文档,里面说明的时候就说委托他是一个引用类型的数据类型,也相当于Java里自定义一个对象,然后在对象里设置属性,通过新建这个对象设置他的属性,也通过这个对象获得他储存的属性数据。我们自定义的对象就是一个引用类型的数据类型,他在运行的时候只是充当一个地址和路标的作用,实际上不储存任何数据,我们是通过他记录的地址信息,去找到真实的数据,这可能要涉及到堆栈,一个负责存放真实的数据,一个负责存放引用数据的地址。这是我看后的感觉,如果有不对的地方,欢迎大佬们指正!
定义
如何在代码中声明一个委托,只要像创建方法一个就行,在前面加多一个delegate即可
public delegate void TestDelegate();
这是自定义的委托,c#里有自带的Action 和 Func委托类
第一个是可以传入参数,但不给返回值的委托
第二个是有返回值,也可以传入参数的委托
查看他们的类,你也能看到他们其实也是自己在创建的时候添加了delegate这个属性来定义他是一个委托的
使用
当存在传入参数类型和数量一致,并且返回值类型也保持一致的多个方法的时候,可以统一用委托进行调用,提高代码的可用性,并且如果在这多个方法中如果大致相同,只是部分参数的不同,那个参数也可以使用委托代替。
这里只做学习记录,不做过多的代码演示(就是还没学透)
事件
含义
基于委托,通过委托链接事件的拥有者和响应者,分别调用他们各自的办法
相较委托更安全,因为使用事件只能对事件进行添加减少,不能获得其他的方法,防止了数据污染和非法调用,而且通过委托可以对事件响应者要调用的方法进行约束,减少bug出现的频率
一个完整的事件应该包括
事件拥有者,事件,事件响应者,事件处理器以及事件订阅
拥有者就是发送消息的对象,需要在这个对象里写好需要发送的内容并且调用事件,事件就是拥有者需要做的事情,事件响应者就是收到要进行事件的对象,而事件处理器就是响应者收到消息后要做的事情,事件订阅就是将事件拥有者和事件响应者之间进行连接
使用
using UnityEngine;
//先定义一个委托
public delegate void CatCallEventHandle();//这个就是事件订阅需要的条件之一
public class Test : MonoBehaviour
{
//定义一个猫类
class Cat{
//定义一个事件,绑定委托
public event CatCallEventHandle CatCall;
//定义猫叫类
public void OnCall(){
Debug.Log("CatCall");
//启动事件,也即是发送消息
CatCall();
}
}
//定义一个人类
class People{//事件响应者
//定义人醒了的方法
public void PeopleAwake(){//事件处理器
Debug.Log("人醒了");
}
}
//定义鼠类
class Mouse{//事件响应者
public void MouseCall(){//事件处理器
Debug.Log("鼠叫");
}
}
//创建启动方法
void Start(){
Cat cat = new Cat();
People people = new People();
Mouse mouse = new Mouse();
//给事件添加需要发送消息的对象
cat.CatCall += new CatCallEventHandle(people.PeopleAwake);//将需要调用的方法传给委托
cat.CatCall += new CatCallEventHandle(mouse.MouseCall);//事件订阅中
//启动猫叫的方法
cat.OnCall();
}
}
运行
大致的流程就是先创建委托,这个委托的入参和返回都需要提前设计好,后面在发送消息的时候如果事件响应者和委托的入参或者返回值不同都无法正常运行
总结,可能运用时候不会很难,但是原理要搞懂还是需要花时间
后面需要使用事件和委托去实现任务系统。加油吧~
2022.08.18更新
上面的代码可以简写成
cat.CatCall += people.PeopleAwake;
cat.CatCall += mouse.MouseCall;
之前那样写是因为视频这么写, 也没有说可以简写,可能是为了更方便我们理解(但其实我反而更不好理解了 …)
总而言之,最近又重温了一遍这四个关键词,下面是我的个人感受
推荐一个视频,这个视频讲的真的很容易理解
https://www.bilibili.com/video/BV1LT411L7yv?spm_id_from=333.788.top_right_bar_window_history.content.click&vd_source=a9f1c2747f921195810879a90b078430
delegate用法: delegate void 委托名(形参); -----委托可以看做是类
委托名 方法名
event用法; 可以看成和void一样的存在------限制不让委托的方法被外部类清空(重点是不让外界=,也不允许在外部类执行,但是可以+=和-=,+=和-=的范围没有限制,其实个人感觉这样好像还是可以污染委托…)
Actino用法:Action<参数类型> 名称;
Func用法:Func<参数类型,返回值> 名称; ----<>里最后一个参数作为返回值
以上的委托事件等用法都必须保证里面不为空,再去执行,否则会报错!