学习BeaverJoe总结。
事件完整声明格式
!事件是靠委托实现的。
首先声明一个类,周杰伦。
概念 | 实例 | 备注 |
---|---|---|
自定义委托 | releaseNewAlbumEventHandler | EventHandler事件处理器后缀,是约定俗成的规范 |
委托变量 | releaseNewAlbumEventHandler | 声明一个委托变量 |
委托注册为事件 | HasReleaseNewAlbum | 发售新专辑,这个事件,用ReleaseNewAlbumEventHandler类型的委托实现 |
添加处理器 | add{ releaseNewAlbumEventHandler += value; } | 别人的方法要绑在上面声明的委托变量上 |
移除处理器 | remove { releaseNewAlbumEventHandler -= value; } | 别人的方法从绑在上面声明的委托变量上移除 |
现在订阅了 「发售新专辑」事件的方法,虽然Jay不知道谁用什么方法订阅了这个事件,但是他在发售新专辑的时候,会调用releaseNewAlbumEventHandler这个委托。
public class JayChou : MonoBehaviour
{
public static JayChou instance;
private void Awake()
{
instance = this;
}
// 定义一个自定义委托,无参数无返回值
public delegate void ReleaseNewAlbumEventHandler();
// 声明一个自定义委托变量
private ReleaseNewAlbumEventHandler releaseNewAlbumEventHandler;
// 将委托注册为事件
public event ReleaseNewAlbumEventHandler HasReleaseNewAlbum
{
// 添加移除处理器
// 告诉事件,添加新的方法和移除方法,就是绑定自己的委托,形成多播委托
add
{
releaseNewAlbumEventHandler += value;
}
remove
{
releaseNewAlbumEventHandler -= value;
}
}
public void Release()
{
// 调用委托
releaseNewAlbumEventHandler?.Invoke();
}
}
Jay在Instagram上调用发售方法。
public class Instagram : MonoBehaviour
{
private void Update()
{
if (Input.GetKeyDown(KeyCode.A))
JayChou.instance.Release();
}
}
不同的类,用不同的方法,订阅了发售新专辑这个事件。
public class FanA : MonoBehaviour
{
private void OnEnable()
{
JayChou.instance.HasReleaseNewAlbum += BuyNewAlbum;
}
private void OnDisable()
{
JayChou.instance.HasReleaseNewAlbum -= BuyNewAlbum;
}
void BuyNewAlbum()
{
print("买新CD!");
}
}
public class FanB : MonoBehaviour
{
private void OnEnable()
{
JayChou.instance.HasReleaseNewAlbum += GoCrazy;
}
private void OnDisable()
{
JayChou.instance.HasReleaseNewAlbum -= GoCrazy;
}
void GoCrazy()
{
print("我要在社交媒体上到处转发,终于等到了,要疯了!");
}
}
public class MilkTeaCompany : MonoBehaviour
{
private void OnEnable()
{
JayChou.instance.HasReleaseNewAlbum += BusinessCooperation;
}
private void OnDisable()
{
JayChou.instance.HasReleaseNewAlbum -= BusinessCooperation;
}
void BusinessCooperation()
{
print("找杰伦代言奶茶!");
}
}
当事件被触发,调用时:
事件的简略声明格式
效果是一样的。
// 定义一个自定义委托
public delegate void ReleaseNewAlbumEventHandler();
// 用委托声明事件
public event ReleaseNewAlbumEventHandler HasReleaseNewAlbum;
// 直接把事件当多播委托用
public void Release()
{
HasReleaseNewAlbum?.Invoke();
}
用官方准备的事件相关基类:
EventArgs是事件有关参数封装的类,EventHandler相当于委托基类。
public event EventHandler HasReleaseNewAlbum;
public void Release(object sender, EventArgs e)
{
HasReleaseNewAlbum?.Invoke(sender, e);
}
private void GoCrazy(object sender, EventArgs e)
{
print("我要在社交媒体上到处转发,终于等到了,要疯了!" + " 来自" + sender as string);
}
private void BuyNewAlbum(object sender, EventArgs e)
{
print("买新CD!" + " 来自" + sender as string);
}
private void BusinessCooperation(object sender, EventArgs e)
{
print("找杰伦代言奶茶!" + " 来自" + sender as string);
}
调用
public class Instagram : MonoBehaviour
{
private void Update()
{
if (Input.GetKeyDown(KeyCode.A))
JayChou.instance.Release(gameObject.name, EventArgs.Empty);
}
}
用Action和Func委托也是可以的。
//public event EventHandler HasReleaseNewAlbum;
public event Action<object ,EventArgs> HasReleaseNewAlbum;
具体什么情况,需要什么样的参数,按照什么样的规范,可以灵活应变。总之,最好用事件代替多播委托,会更加规范,限制更严格,不容易出岔子。事件不会允许非“+=、-=”操作符,就是一个包装好的,成熟的多播委托范例。
是 发布者/订阅者模式 或者说 观察者模式 版本的多播委托。