10.29.2011

What iOS Simulator does not simulate: free()

在開發iOS app時一定要用實機測試,因為simulator跟實機的行為很多地方並不相同。Simulator除了不支援某些硬體功能外,在根本的運作機制上也有不同,這篇要分享的是在memory上的運作機制。

不過我也不打算寫太長,只寫要注意的地方就好了(因為太晚了~)。
我們先來看一段將Pixel array轉成UIImage的程式碼:

// 產生要畫的圖
unsigned char *pixels = malloc(nImageSize);
/*
 * (省略繪圖步驟)
 */
// 用畫好的圖產生image用的context
CGContextRef context = CGBitmapContextCreate(pixels, width, height, ...);

// 用完的記得要還,要養成好習慣!
free(pixels);

// 產生UIImage
CGImageRef imageRef = CGBitmapContextCreateImage(context);
UIImage image = [UIImage imageWithCGImage:imageRef]; 

// 要release才不會leak
CGContextRelease(context);
CGImageRelease(imageRef);

這段code在simulator能將pixels正確地轉成UIImage,使用Intruments也沒有發現memory leak,看起來沒問題吧!

很不幸地,在iPhone上完全不是這麼回事,你只會看到一片空白。

你看出問題在哪了嗎?是的,問題就在於pixels太早free了!應該要產生完image之後再free pixels。在iPhone上執行時,一呼叫free就會將memory清掉了,但simulator是在Mac OS上面執行,呼叫free時模擬的行為可能跟在iOS上面不一樣(可能是因為Mac OS X有GC的機制而iOS沒有)。如果只在simulator上面執行,就永遠找不到這個bug了!

所以如果你有在程式碼中呼叫free的話,記得在實機上也要測過喔!

P.S. 以後有機會再來分享在Android emulator中開發的心得。話說用i7-2600K來跑Android emulator還是很慢啊...

10.28.2011

追求細節

寫程式或是做產品跟畫漫畫其實有很多相似的地方,除了都是追求藝術外,也都講究細節。
這邊我所謂的細節不是指筆觸多精密,而是指漫畫中沒有留白的地方。

許多人看漫畫其實是在看“有圖的小說”,意思是說除了主要人物跟對白以外其實並沒有注意太多畫面上的細節(例如貼網點),而這些是使得畫面更加圓滿的必要元素;諷刺的是,當這些細節不存在時才會被人注意到似乎少了什麼東西,或是更直接一點就罵作者太混(我絕對不是在說富X)。

產品也是這麼回事,許多的小細節能使平凡的產品變得與眾不同,而堅持做出這些小細節的你也就變得與眾不同。

題外話:過度設計跟沒有細節一樣糟糕。

9.19.2011

[雜談] 近況更新

距離上次在這邊發文已經過了一年多了,更新一下近況順便做點記錄。

首先是...我又失業了 XD (Yeah~繼續練功~)

其實已經離開公司一陣子了,這段期間雖然也有許多公司的邀約(例如HTC),但是都婉拒了。每次HTC打來都很想問他們"我可以事情做完6點就下班嗎?"
工作也好些年了,好不容易對某些事情有了熱情,於是想趁還年輕、還沒有家庭跟小孩的時候好好去闖。

之前Android也玩了幾年,最近則開始接觸Apple iOS的開發,之後也會陸續分享在iOS上的開發心得,敬請不要期待,haha。

最後就是要給自己的小提醒:

我是很討厭加班文化的人,尤其是常態加班,那簡直是慢性自殺!
台灣人總覺得衰事不會輪到自己,而我過去就因為每天熬夜寫code到最後搞壞身體,差點連命都沒了。
長期加班也會造成效率低落的惡性循環,變成晚上寫bug白天debug。
我一直期許自己能在架構以及實作上做到預防勝於治療,對我來說一個好的工程師可以解很多bug,但是優秀的工程師能少寫幾個bug。(能寫到沒bug的稱為神)
因此我要求自己要在上班時間內提高效率做完當天的工作,不管上面長官會不會因此黑掉我。

但是這幾天晚上都寫到2, 3點,今天警覺到惡性循環的開始:昨晚寫的東西有32 bytes的memory leak,結果今天又花了一個早上來抓漏,最後發現是某個該用assign的property寫成了retain。Oh,也許有人說32 byte leak算什麼,但是我相信最不起眼的問題總有一天會在最不希望的時候反咬自己一口。

雖然有點經濟上的壓力,但是要相信自己,就算不加班不熬夜也可以做到!

8.20.2010

[舊稿] [Q&A] Layout of blogger 版面配置

發現這篇從08年年底到現在一直在草稿狀態,雖然只有一點點,不過還是貼上來好了,因為接下來不知道什麼時候才有時間更新...

偶爾嘗試點不同的寫作風格,就先用這篇開刀好了。本來想用敘事的方式來說明一下這個blog的排版原因和某些小細節,不過寫一寫發現有點難閱讀,所以改用Q&A的方式看看會不會有所改善。以下是左腦跟右腦的訪談:

Q:感謝你接受我的訪問,能不能請你大概聊一下整個版面的設計理念?
A:我希望我的讀者能在第一眼就很清楚文章的位置在哪裡,尤其是使用手持式裝置(PDA、SmartPhone甚至PSP)的讀者,這樣的讀者已經愈來愈多了。當然我也想提供行動裝置版的版面,不過在Blogger現有的template下是蠻難實現的。除此之外,在右側我放了一些Gadget,主要是希望能多些人交流。

Q:那配色呢,有什麼特別的原因嗎?
A:我想藍色是很貼近科技本質的一種顏色,所以我就用它當標題的顏色了。我曾經在白底黑字跟深底淺字兩種方式做徘徊,深底淺字的好處包括對行動裝置來說比較省電、對眼睛來說比較溫和,但是白底黑字才是大多數習慣閱讀的方式,另一方面由於blog可能會出現大量的貼圖,我不太喜歡貼圖跟背景色的反差太大(我想很多人都有在深色投影片貼過圖的經驗),所以最後選擇的是白底黑字。

在Framework中加入自己開發的API

大家好久不見,今天要分享的是如何將自有API跟系統一起build並且能將build出來的SDK放在Eclipse裡面用,不過這招不適合要放到android market上的程式,如果是這種情況,你需要的是git並且做好管理(包括把Eclipse的sync選項打開,好像越扯越遠...)

我想很多人應該也跟我一樣,開發程式時會寫出很多共用的API(通常是utility API),或是很多程式都會去bind同一樣一個service,而這些code(包括AIDL檔)通常會有很多份copy在各個Eclipse的project內,造成sync上的問題。這還不是主要的問題,更主要的問題在於,如果你的程式用到了hidden API,那可是連在Eclipse中build都build不過,更別想直接跑在emulator或是透過新版adb install到target上(因為Eclipse有error就無法產生apk檔)。

為了解決這兩個問題,我想最好的方式就是把code放在frameworks中一起build,而build出來的SDK正好可以給Eclipse用。

假設今天com.blogspot.dejob這個package有a.java及b.aidl要放進framework,那麼請試著這麼做:
1. 把這兩個檔案放在frameworks/base/core/dejob/java/com/blogspot/dejob/底下
2. 更改build/core/pathmap.mk,在FRAMEWORKS_BASE_SUBDIRS最後面加上"dejob \"
3. 更改frameworks/base/Android.mk:
  • 在LOCAL_SRC_FILES這一段的最後加入dejob/java/com/blogspot/dejob/b.aidl,這樣就可以讓AIDL檔build到framework中,但是這樣還不夠,你還需要下一步才能將AIDL檔內的javadoc build到SDK的document內。
  • 在aidl_files這一段的最後加入frameworks/base/dejob/java/com/blogspot/dejob/b.aidl
  • 在packages_to_document這一段的最後加入com/blogspot,意思是說com.blogspot底下的所有package都build進document。
4. 照下列順序來build code:
  1. 先確認你不是用root權限來build code!
  2. 裝好所有toolchain及下載android source code(騙一點篇幅,雖然沒稿費...)
  3. 切換到android目錄下打". build/envsetup.sh",請注意最前面那個"點"
  4. lunch sdk-eng
  5. make sdk
5. 接下來就可以先去運動一陣子(除非你的電腦配有12 core CPU+SSD RAID+16GB以上的RAM)

如果你的code沒寫錯,應該就可以看到SDK已經build完並且壓成zip檔了,接下來只要將這個zip檔解開,然後在Eclipse中指定SDK的位置到這個目錄就可以了。另外也建議在Eclipse的project中選clean將project重新build一次才能知道有沒有成功。

講一些題外話,最近一直在想要不要去應徵聯發科的android工程師,不過應該會被打槍吧,不知道還有沒有其他android相關的工作...

6.15.2009

在Eclipse下看framework的source code

參考: View Android Source Code in Eclipse

簡單來說,trace ADT的code會發現ADT會去android.jar同個目錄下的sources這個目錄找source code,
所以我們只要將android的java source code撿一撿,照package放到sources這個目錄就可以了。
所以參考link中的python script就是在幹這件事,不過我有兩點建議:
1. 在沒有make過的source code目錄下執行這個script:因為out這個目錄下有重複的java code
(而且out這個目錄有夠肥)
2. 把zippath = match.group(1).replace('.', '/') + '/' + file改成
zippath = 'sources/' + match.group(1).replace('.', '/') + '/' + file
這樣解出來的檔案和目錄就會放在sources目錄裡面了.

最近還在研究怎麼debug native code,之前make的gdb不能debug multi-thread的程式 = ="
看看android-ndk有沒有進展好了

6.14.2009

Eclipse JEE vs Java 6 Update 14

如果你更新到Java 1.6 Update 14, 而且原本能跑的Eclipse突然不能跑的話,
將eclipse.ini中的-Xmx512m改成--launcher.XXMaxPermSize所指定的size試看看,
我是改成-Xmx256m就能跑了