2013年3月7日 星期四

forget() 的妙用

Gecko 的程式碼裡面用了很多 share pointer, 利用 reference count 來決定所指向的物件是否應該被刪除. 其中常會看到一些有趣的眉角, 像是 .forget() 這個函式, 會回傳指向物件的位址, 同時清除這個 share ptr 對此物件的所有權. 使用時機像是:

function f()
{
  nsRefPtr obj = new Object();

                   ...
                   ...

  nsRefPtr r = new nsRunnable(obj.get());   // !!!!!
  NS_DispatchToMainThread(r);
}

就上面這個例子而言, 驚嘆號的那行顯然就是會有問題的地方, obj 所指向的物件, 由於 obj 的生命週期隨著 f 這個函式終止而到期, 所以我們沒有辦法保證 r 這個 runnable 在執行的時候, obj.get() 還是有效的. (事實上, 有效的機會很低)

針對這個狀況, 我們必須使用 obj.forget() 以消滅 obj 對於所指向物件的擁有權.

  nsRefPtr r = new nsRunnable(obj.forget());

這樣就可以了. 經典範例請見此