最近在學習Unirx,發現Unirx的消息系統MessageBroker很不錯。我先展示一下用法:
//註冊消息
MessageBroker.Default.Receive<int>().
Subscribe( ( i ) =>
{
Debug.Log( "Count" + i );
} );
//發送消息
MessageBroker.Default.Publish<int>( 1 );
使用起來非常簡單,耦合性也非常低。但是它和其他消息系統一樣有一個毛病,就是有註冊消息就必然有移除消息。
如果沒有在適當的時機進行移除就會多次調用方法,比如在本例中,我把註冊消息放在MonoBehavior的 OnEnable中,那麼當我多次Enable的話,就多註冊多個事件,當我發送消息時就會調用多次,顯然不是我想要的。
Unirx提供了幾種移除消息的方法,我按照實用度依次來講講:
1.Subscribe後接AddTo(this),適用於MonoBehavior
寫法如下:
MessageBroker.Default.Receive<int>().
Subscribe( ( i ) =>
{
Debug.Log( "Count" + i );
} ).AddTo( this );
寫了這個後會在GameObject的OnDestroy裏面進行移除消息。這個做法只能用於MonoBeahvior,侷限性很大,因爲在實際項目中不是MonoBehavior的東西多了去了,比如玩家的buff,玩家身上的道具等。而且只能在OnDestroy裏面,但凡是個正常的項目,肯定都會用對象池,會把物體Disable而不是直接消耗,當我從池子裏拿出來時消息卻沒有移除肯定是不行的。其實這個的原理就是第二條,Unirx在你調用AddTo之後會自動創建一個ObservableDestroyTrigger的東西掛在GameObject上,這上面有一個CompositeDisposable。
2.使用CompositeDisposable,適用於一個類上需要註冊多個事件的
CompositeDisposable可以將多個IDisposable組合,然後一口氣清除,寫法如下:
CompositeDisposable com = new CompositeDisposable();
private void OnEnable()
{
com.Clear();
MessageBroker.Default.Receive<int>().
Subscribe( ( i ) =>
{
Debug.Log( "Count" + i );
} ).AddTo( com );
MessageBroker.Default.Receive<int>().
Subscribe( ( i ) =>
{
Debug.Log( "Count" + i );
} ).AddTo( com );
}
我只需要在註冊之前(或者其它時候),調用CompositeDisposable的Clear就可以了。
3 .使用SerialDisposable,適用於一個類上註冊一個事件
SerialDisposable有個很牛逼的地方,它的Disposable每次賦值後會把上次賦值的IDisposabel給釋放掉,於是乎就可以這麼寫
SerialDisposable _disposable = new SerialDisposable();
private void OnEnable()
{
_disposable.Disposable = MessageBroker.Default.Receive<int>().
Subscribe( ( i ) =>
{
Debug.Log( "Count" + i );
} );
}
如果還覺得不得勁,可以這麼寫
_disposable.Disposable = MessageBroker.Default.Receive<int>().
Subscribe( ( i ) =>
{
Debug.Log( "Count" + i );
_disposable.Dispose();
} );
這樣Subscribe只要執行一次後,就會自動釋放掉。
感覺終於可以和噁心的+=和-=說再見了
好久沒寫博客了,再不寫點感覺人都要廢了,最後安利一波我的交♂流羣 891809847