ObjC 的記憶體管理之今晚你想吃哪一道

好像很多人在接觸 Objective C 開發的時候,在 alloc、retain、release 花了很多力氣,三不五時就看到有人在問這方面的問題。然後有時候看到網路上面的程式碼教學或分享,稍微一看,裡頭在記憶體管理方面的問題也不少,有的是忘記 release 物件,有時你會看到,[NSWorkspace sharedWorkspace] 都有人 release。

說實在,在不是 Garbage collection 的模式下寫 ObjC,大概就是像開手排車一樣,開始使用一個物件的時候就是推到一檔,每多使用一次、多 retain 一次物件,就像是打到了二檔、三檔,最後不再用到這個物件的時候,就是打回空檔。

所以,要比較正確的管理記憶體使用,也會跟開打檔車一樣,需要的不僅只是了解,而是要養成習慣,成為寫程式的時候身體反應的一部分,既然是要養成習慣,就恐怕不是在網路上或是哪裡抓個人問就可以解決。而這個習慣不外乎幾點-大概只有成員變數需要 retain、成員變數在 dealloc 的時候要記得 release,在寫 setter 的時候把原來的成員變數 release 掉並且 retain 新傳來的變數,一般在 method 之間傳遞的變數加上 autorelease,至於 singleton 的物件,就別 release 了。

個人經驗是,大概寫了幾千行 ObjC 之後,記憶體管理的習慣就會豁然清明開朗,先別苦惱,多寫就對了。而不管怎樣,有時候還是會弄錯,如果你在用 Mac OS X 10.6 上面的 Xcode,Xcode 有一個叫做「Build and Analysis」的選項,會在編譯的時候,幫你把忘記 release 的物件找出來。

如果你花了一定時間,還是對於 ObjC 的記憶體管理苦手的話,呃,那不如這樣-都不要 release 物件。

如果你是寫 Mac 上面的程式,Mac OS X 10.5 就已經支援 GC 了,你就接把 target OS 設成 10.5 以上開始寫程式,別去管 10.4 之前的版本,蘋果前幾天的安全性更新已經沒有供 10.4 的版本,等於是非正式公布了-蘋果自己都已經不支援 10.4,那何必還要去支援蘋果都不支援的東西呢?而到現在還不清楚 ObjC 的記憶體管理,大概寫的也是新的程式,從很功利的角度來看,不願意更新作業系統的使用者,就會有意願花錢買新的軟體嗎。

iPhone OS 到目前為止還沒有 GC,而不 release 記憶體,有記憶體沒有回收,就會產生 memory leak。不過,使用者一次會使用你的應用程式多久呢?目前 iPhone OS 限制一次只能使用一個程式,所以每個程式進出都很快,可能是簡單查一個資料,然後就關閉了,前後時間可能三十秒不到。

記憶體管理沒做好,不外乎兩種狀況-一種就是物件都沒有釋放造成 memory leak,另外一種狀況就是 over-release,釋放了不該釋放的物件,然後在存取這個物件的時候發生 bad access exception。發生 bad access exception,程式就會馬上當掉,而 iPhone 上發生 memory leak,當記憶體用量大到一定程度(在 iPhone 3G 上大約是 40MB,至於3Gs,我還沒有機器可以測),iPhone OS 也會強制關閉關閉應用程式,看起來也很像是當機。不過一個是馬上當掉,一個是在一定時間之後才會發作,就看今晚你想要吃哪一道,或是今晚你想要被哪一道吃。

而既然只有三十秒,memory leak 又能夠多嚴重,漏水就讓他漏嘛。你可能會說,iPhone 在 Jailbreak 之後,就可以讓程式在背景執行,如果不處理好,memory leak 還是會相當嚴重-不過,既然都已經 JB 了,你覺得多少 JB 的使用者會花錢購買你的軟體?既然沒有花錢,那對他們那麼好做什麼…。

總之,在 iPhone 上的 memory leak,要不就是在漏水漏到很嚴重之前,程式就已經關閉了,要不就是發生問題的人,本來就對你的生意沒什麼影響。-綜合評估下來,就是沒有什麼問題嘛。而且等你搞熟了怎樣 retain、release,以蘋果改版的速度,在 iPhone 上的 GC 大概也都做出來了。

當然,最後還是要把如何管理記憶體的技能或習慣培養起來。就像能夠開手排車算是專業駕駛的素養,知道怎麼手動 retain、 release,也是 Objective C developer 的基本素養呵。

延伸閱讀:为什么重复free()比内存泄漏危害更大

Be Sociable, Share!

9 thoughts on “ObjC 的記憶體管理之今晚你想吃哪一道

  1. 怎麼讀了中間那一段,感覺像是:”反正他沒花錢,所以你的軟體寫不好不是你的錯。”
    自己生出來的小孩,還是得要生得優一點呀,呵呵。

  2. Pingback: [CS193P] 史丹佛大學的iPhone應用開發課程:第三堂課摘要及心得筆記之二 | 網路趨勢行銷與開發

  3. Pingback: [CS193P] 史丹佛大學的iPhone應用開發課程:第三堂課摘要及心得筆記之一 - Inside

  4. 我倒是很認同作者的觀點
    因為讀到一篇優質的文章,所以我nice一點,呵呵

    這世界上有很多人非常的白目,的確是不用對他們這麼好沒錯的….

  5. Pingback: [ObjC] 關於Objective-C的記憶體管理 | Abe's Programming Notes

Leave a Reply