The Old Blog Archive (Traditional Chinese), 2004-2009

Archive for April, 2009

看懂 iPhone view controller 記體體管理的原則(或者:didReceiveMemoryWarning 到底在搞什麼鬼?)

當 iPhone 或 iPod Touch 的記憶體不夠用的時候,當前 app 的所有 view controller 物件都會收到 didReceiveMemoryWarning 呼叫。你可以把它當成像 NSNotification 一樣的事件。

系統預設的 didReceiveMemoryWarning 實作(你一定用得到,因為你得呼叫 [super didReceiveMemoryWarning])是,如果當前 controller 所擁有的 view 沒有其他 superview (通常代表意思是沒被顯示出來,例如,埋藏在 navigation chain 或其他 tab 當中),那這個 view object 就會被是放掉。

如果你的 controller 只有這個 view 物件,事情就到此為止。不過我們都知道人生從來不是這麼簡單的。

尤其,如果你的 controller 當中宣告了從 nib 載入了 IBOutlet 物件。根據 Apple 文件,xib 載入的時候所有的 IBOutlet 物件都已經至少有了 retain count 1 。這些物件通常也都被你的 view 物件所擁有,所以通常等你用到他們的時候,他們的 retain count 都至少是 2 。

但是你的 view object 被放掉時,這些 IBOutlet 還被 retain 著。所以你要做兩件事:

  1. 在 view 被放掉時,也同樣放掉你的 IBOutlet
  2. 在你的 controller 被 dealloc 到時,也放掉你的 IBOutlet ,同時將他們的 pointer 設到 nil

iPhone SDK 一直到 2.2.1 都沒有好方法讓你做到 1. ,所以請參考 Craig Hockenberry 的這篇文章 ,簡言之就是要去 override -[UIViewController setView:] 才有辦法在 view 被放掉時也同時放掉那些 IBOutlet

(雖然事實上,如果你照著 Apple 最新的 coding 規範,將 IBOutlet 都設為 readwrite retain property,那麼在你的 controller 下次再度載入 view 時,這些舊 IBOutlet 都會被放掉,但是呢,如果你的 IBOutlet 很肥,例如滾輪式選單,那麼最好是放掉他們)

然後呢,在你的 controller 要被 dealloc 的時候,記得放掉你的 IBOutlet 物件,同時將指標設到 nil。Apple 文件有說明原因:因為當你最後呼叫 [super dealloc] 的時候,你的 view object 會被放掉,然後如果你已經做了 1. ,view 被放掉時去釋放 IBOutlet,偏偏你早就已經在 dealloc method 前半部 release 了他們,那麼接下來就會有人對死掉的指標值(所謂的「當夠了物件」──dangling object)送出 release 訊息,那就爆炸了…

總之,iPhone app 在記憶體使用上的最高指導原則是 lazy loading。要用的時候才載入,不用的時候就放掉且將指標值設為 nil ,最不容易出錯。這也是 Apple 從 Objective-C 2.0 時代開始大量推薦使用 @property 的另一個原因。

少年推特的煩惱

@werther 想要追 (follow) @charlotte,但是後者一看到 @werther 追了太多人,當下就把他 block 掉了,so……

近期投影片彙整

以下是最近幾個月所做過三場演講的投影片彙整:

TapExpense 2.2 發表

這次 Apple 讓我們等了一下,TapExpense 2.2 終於上架了!

這一版 TapExpense 新增了匯率轉換的功能,在「報表」分頁中選「設定」,就可以選擇要使用的主要貨幣。選完後,您可以自行設定各貨幣的匯率,或者讓 TapExpense 去網路上自動幫您取得匯率。有了匯率資料後,報表內的每一筆加總就會同時顯示原幣值跟使用主要貨幣的總計,這樣一來在外旅行時要掌握花費就更輕鬆了。

同時這一版還修了兩個 bug。

一個是 2.1 版中的圓餅圖有一段 code 有 bug ,所以當您有收入項目的時候,有一些支出的餅可能會消失。2.2 不但修好了,我們也讓圓餅圖的文字標籤安排更好看。

另一個 bug 是,如果您已經在使用某個 beta 版本的 iPhone OS ,TapExpense 也終於可以在上面正常使用了。圓餅圖在某 beta 版本上有一點點怪怪的地方,我們也在繼續修正中。

感謝大家等候!

(TapExpense 是 iPhone/iPod Touch 用的記帳軟體,有美金 4.99 的付費版免費試用版。如果您有 iTMS 美國帳號,下載過試用版後寫了 blog 或 Twitter 將網址寄給我們,就可以收到正式版的 coupon code。請寄信到 contact {at} lithoglyph {dot} com 註明索取 TapExpense 正式版 coupon 跟介紹文字網址。數量有限,歡迎索取!)

重新開始:ObjectiveFlickr 2.0 for Mac and iPhone

這件事情隔了好久,終於起了個頭。

ObjectiveFlickr 2.0 是一套 Objective-C 寫成的 Flickr API framework。如果你正計畫開發使用 Flickr API 的 Mac 或 iPhone 程式,ObjectiveFlickr 說不定可以幫上忙。

這是完全重寫過的版本。更重要的是:裡面有一套完整的 iPhone 照片上傳程式的範例。所以 ObjectiveFlickr 也可以當做 iPhone 程式開發的教材。同樣還附有 Mac 跟命令列工具的範例。

最早的 ObjectiveFlickr 是在 2006 年 9 月時開始寫的,2006 年年底時曾經全部重寫過一次。2007 年初開始穩定下來後,就一直沒再動過。但之後 OS X 10.5 出版,iPhone SDK 出現,原來設計框架的許多假設、使用的寫作風格、當初設想的應用方式,都發生了變化。原有的衣服不合身的,於是到了重新訂做一套的時候。

這是 open source 軟體,使用 MIT 授權條款發佈。

有興趣的朋友可以從 github 取得 ObjectiveFlickr 的程式碼。建議先讀過新版本的 README──這也是本次改版的重要特色之一喔。

http://githib.com/lukhnos/objectiveflickr

另外參閱:英文版的發佈說明 / announcement on Flickr group