2010年9月26日 星期日

檢查MacBook Pro的硬體錯誤

一般來說,當安裝了新硬體之後出現問題,通常就是得自己想辦法從混亂的情況中,找出可能的原因。尤其是安裝了像是RAM或CPU這類的東西。有時候新的RAM有問題或是不合於目前硬體,是不會造成無法開機,但是就會讓你出現很多類似靈異現象的事。

在Windows中,至少我所知道的,就是只能用自己經驗跟third-party的硬體檢測軟體來判斷。但是每套硬體檢測軟體的結果又都不太一樣。

最近,我幫我的MacBook Pro加到了8GB,本來很高興的要工作,但是卻一直有很多不太正常的事...當然,很直覺的就判斷可能是RAM的問題。但是,該怎麼確定呢?於是Google了一些軟體做檢測,但是結果也是時好時壞。
但是後來發現,原來...Apple在出廠時所附的Application installation disc中,就有「Apple Hardware Test」的程式。只要把該片放入光碟機之中,然後在開機時按住「d」,就可以進入「Apple Hardware Test」,檢測很簡單,就是「標準測試」與「延伸測試」兩種。基本上,如果連標準測試都沒辦法過,就是有很明確的問題了。而我的問題在連續三次的標準測試都指出是RAM的問題...所以當然就是去創見處理囉~

結論:再也不用為了硬體檢測問題傷神了~

2010年9月25日 星期六

在Ubuntu Server Edition上安裝GUI介面

想把server改成用Ubuntu Server,但是又不想只用command line的方式來管理與設定系統。所以就想到在Ubuntu Server上面裝上gnome...但是又不想安裝完整的gnome

在參考How to install GUI in Ubuntu Server之後,自己就試著用
sudo apt-get install x-window-system-core gnome-core
結果真的可以安裝很簡易版本的gnome...幾乎沒有任何GUI app...連synaptic都沒有,所以只好再用apt-get來安裝

2010年8月5日 星期四

DOM-based XML utility For iPhone

在Mac OSX上,分別有NSXMLParserNSXMLDocument來處理有關SAX與DOM方式的XML parsing。然而在iOS上的Cocoa Touch,卻只剩下SAX的NSXMLParser的處理方式。相較於DOM來說,SAX的處理方式是較為快速與節省資源的,也或許是這樣才會在iOS上只保留這種方式的parsing。

然而,如果只是簡單格式的XML讀取,用NSXMLParser來parse可能是很快速簡便。但是如果要處理的XML格式眾多或是格式複雜,那就可能不是那麼好過了...而且NSXMLParser也只能處理讀取時的parsing。如果是要將資料輸出成XML格式,那不使用DOM的處理將會變得比較難以處理。

後來在internet上,發現這篇APXML: NSXMLDocument 』substitute' for iPhone/iPod Touch,才知道有這個APXML的DOM-based簡易套件可以使用。說它是簡易套件還真不為過,含Header file在內,全部也才不過6~7個source code files,每個也都不算太大、太複雜。
既然是DOM-based parser,當然除了可以讀取,也可以輸出成為XML。使用上很簡單,只要
#import "APXML.h"
就可以使用到全部的相關類別,不必一一去import個別的class。
Parse XML:
APDocument *doc = [APDocument documentWithXMLString:xmlstring];
取得Root Element:
APElement *rootElem = [doc rootElement];
讀取所有子element:
NSArray *childElements = [rootElem childElements];
讀取element name:
NSString *elementName = elem.name;
讀取element value:
NSString *elementValue = elem.value;
讀取特定名稱之attribute:
NSString *attrValue = [elem valueForAttributeNamed:attributeName];

輸出部分則為
Create Element:
APElement *elem = [APElement elementWithName:elementName];
Set attribute & element value:
[elem addAttributeNamed:attrName withValue:attiValue];
[elem appendValue:elementValue];
Add child element:
[elem addChild: childElem];
Create XML Document:
APDocument *doc = [[APDocument alloc] initWithRootElement: elem];
Output XML string:
NSString *xmlString = [doc xml];

使用語法算是十分簡單、直覺。
其實,要自己實作DOM-based parser也不算太難,但是總是比較費工夫、品質也需要時間來鍛鍊。既然有現成又不錯的lib,當然能善加利用會更好囉~

好用的HTTP lib(for iPhone & Mac OSX)

HTTP API其實在Cocoa裡面是有的,透過NSURL、NSURLRequest、NSURLConnection等類別來達成,也分別支援同步與非同步傳輸。使用上雖然不算是太難,但是仍然有不少繁瑣的手續要做,要處理的delegate method也不算少,讓人感覺還是有點不是那麼方便。

因此,後來在internet上,找到一個叫做ASIHTTPRequest的lib,這個lib是以BSD license的方式open source的。顧名思義,這個lib的主要工作就是提供HTTP protocol的通訊機制,而且用很簡單的方式讓developer可以操作request、response,以及設定POST parameter,甚至是上下傳檔案等等。本身也內建啟用Cookie機制,所以對於一些有session tracking的web services也很方便。當然也提供有同步與非同步的傳輸。
官網位置:http://allseeing-i.com/ASIHTTPRequest/

心得:該Lib除了可以在Mac OSX上使用外,也可以在iOS上使用,而且目前已經與iOS4相容。使用上算是很簡單,也沒碰過啥大問題。如果要說缺點,就是放到project中,會導致project code在compile之後多出不少容量吧XD

2010年8月4日 星期三

動態調整TableVewCell的高度

因為工作需求,原本要使用UITextView來顯示多行文字,但是發現使用了UITextView之後,Cell可以觸發select動作的區域將變得很小(受到UITextView的區域影響)。所以改用別的方式處理。

首先,發現原來UILabel是可以顯示多行文字的,只要把property numberOfLines設為0,就可以支援多行文字,但是必須呼叫[label sizeToFit],來調整UILabel的大小。

而預設的UITableViewCell的textLabel也可以這樣調整,所以就可以顯示多行文字。然而,UITableView還有個問題,就是有cell height的問題。因為cell height似乎是在cell顯示前就會設定好,所以即使在tableView:cellForRowAtIndexPath:這個method裡面去調整cell的高度也是無效。必須透過tableView:heightForRowAtIndexPath:來回傳特定cell的高度。

但是,對於多行文字來說,因為內容行數是不固定的,所以必須在顯示時計算實際行數文字的總高度。幸好在參考iPhone SDK: Resizing a UITableViewCell to Hold Variable Amounts of Text, Part 2 of 2這篇之後,得到解答。就是利用NSString裡面的sizeWithFont:constrainedToSize:lineBreakMode:來根據指定的字型高度跟斷行方式來計算。可以使用Objective-C的Category機制,將此method放置到NSString中。以下是參考上述文章所寫的code:
@implementation NSString (TextHeight)
-(CGFloat) textHeightForSystemFontOfSize:(CGFloat)size {
//Calculate the expected size based on the font and linebreak mode of the label
CGFloat maxWidth = [UIScreen mainScreen].bounds.size.width - 50;
CGFloat maxHeight = 9999;
CGSize maximumLabelSize = CGSizeMake(maxWidth,maxHeight);
CGSize expectedLabelSize = [self sizeWithFont:[UIFont systemFontOfSize:size] constrainedToSize:maximumLabelSize lineBreakMode:UILineBreakModeWordWrap];
return expectedLabelSize.height;
}
@end

透過此method,就可以在tableView:heightForRowAtIndexPath:中回傳正確的文字內容高度了。

2010年5月12日 星期三

DB實作心得---SQL JOIN語法

因為都是用Hibernate,所以好久沒碰這種語法了...老實說以前在學SQL的時候,也一直沒很認真的搞懂。一直到最近為了案子,才又比較認真的去看了...
找了幾篇網友分享的文章,都講得很清楚,所以就不在贅述:
一般來說,我們通常都會儘量用一個SQL statement的方式來完成所需要的查詢。而其中都儘量可以用JOIN的方式來把所需要的資料串出來。不過我也有看到有網友發表心得,表示在MySQL上,進行較複雜的JOIN時,效率會很糟糕,甚至會造成DB table被lock過久的情況。事實上,幾年前我自己也用過MySQL,也是發現它在作較複雜JOIN時,效率真的不好...所以後來我就都改用PostgreSQL。

而在Hibernate中,我所常用的Criteria是一種物件式的查詢方式,它建立跟其他table JOIN的方式是透過createCriteria()或是createAlias()。透過這兩種method,可以把要查詢的root entity跟child entity作JOIN。在建立這種JOIN關係時,Hibernate預設是使用inner join的方式,所以在某些情況會無法正確的找到所要資料,甚至會出現LazyInitializationException。此時,可以試試看在這兩種method的呼叫時,加上Criteria.LEFT_JOIN,這樣Hibernate會以Left outer join的方式處理,也許就可以成功的找到所要的資料了。

我個人認為與其使用一個很複雜的SQL statement來增加查詢效率,未必比使用多個簡單的SQL statement來取出資料再透過自己程式邏輯作處理來的容易跟快速...

Database系統實做心得---SQL調校

做了很久跟DB有關的開發工作,但是其實後來大部分都是靠Hibernate為主。透過它,開發者不再需要傷神有關DB底層的設定與SQL語法的管理與維護。不過也變得比較偷懶,比較不會去在意SQL語法上的調校。
在網路上有許多高手有此道的獨到心得,我只也是從中獲得一點點,這兩偏是個人覺得還蠻不錯的:Database Index 筆記調校 SQL 以徹底改善應用程式效能

其中有些跟DB table schema設計或是SQL語法的技巧,不過在Hibernate中,要使用這些技巧可能就不是那麼容易。Hibernate是允許使用者自行設定這些東西產生的方法,甚至可以自訂SQL statement。不過個人覺得Hibernate自己所產生的schema跟SQL statement已經很不錯了,除非真的很有特殊的需求,不然實在也沒必要自己搞(如果都要自己搞,那就失去用Hibernate的意義了)。

不過兩篇文章都有提到的一個重點:index。在Hibernate中,也有支援產生index的機制,但是只會對primary key跟unique column自動產生。雖然在Hibernate Annotation Extensions中有@index的annotation可以指定對某個property產生db index,但是這功能只有在透過Hibernate作第一次DB schema建立時有效;若是指定的index的table已經存在的話,這機制不會有作用,就必須手動產生。根據上面兩篇文章的內容,產生與刪除index的SQL DML為:
create index index_mytable_mycol on mytable(mycol)
drop index index_mytable_mycol

而根據上述兩篇文章的講法,幾乎都認為應該對FK也設定index比較好。當然有些但書,例如在主table資料量有到一定量以上的時候才會比較有效果等等的。