2013年9月15日 星期日

STEB 有妙用,可惜不是全世界買單

剛剛從 Oslo 回來, 結束了自己第五次的 workweek (Paris, San Diego, San Francisco, Berlin, Oslo. 中間其實還外帶一次 Half Moon Bay 的 Bluetooth mini workweek), 挪威是個人文和地理都很美麗的國家. 這次回來有個插曲, 就是在奧斯陸登機前買了當地的果醬, 店員問我是直飛還是轉機, 我說會轉機, 然後她就幫我把果醬裝到一個名字叫 STEB 的袋子裡. 在轉機點曼谷下機前, 有個台灣團貌似導遊的人告訴我, 東西裝進這袋子也沒用, 我的果醬在轉機安檢時一定會被沒收, 說是全世界機場皆然. 我當時第一個念頭是那這袋子到底要幹嘛? 小強有跟他說應該不是這樣, 可是對方氣勢超強, 我已經做好放棄的準備了. 後來索性就也不藏了, 直接把它拿出來過安檢, 結果安檢人員拿出來看了看, 確定是果醬而且有用 STEB 裝著就順利放行. 回來以後趕忙查了一下, 每個機場有其不同的規定, 例如香港跟曼谷可以, 但日本境內的機場目前都不接受任何100ml以上的液體通過轉機站安檢, 即便裝在 STEB 也一樣.

真是行萬里路勝讀萬卷書.

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());

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