2015年11月10日 星期二

修正Jenkins在JDK與Maven自動安裝無法選擇的問題

最近使用Jenkins時,發現會有時候在「設定系統」時,安裝JDK與Maven的自動安裝的版本列表是空的TextField,導致無法設定。經過Google之後發現可以用以下方式修正:

  1. 到「管理Jenkins」->「Script主控台」,貼上以下程式碼並執行:
hudson.model.DownloadService.signatureCheck = false
hudson.model.DownloadService.Downloadable.all().each { it.updateNow() }
hudson.model.DownloadService.signatureCheck = true
return
  1. 然後再到「管理Jenkins」->「設定系統」,就會發現版本List已經正常了
以上解決方法是參考:Auto-installer for JDK no longer works

2015年4月7日 星期二

如何刪除Git的Remote branch

如果使用git 1.7以上版本,可以使用以下指令:
 git push origin --delete <branchName>

或是:
git push origin :<branchName>

如果是使用eclipse的egit,可以照以下步驟
  1. 將eclipse切換是Git Repositories的操作畫面下,選定要刪除branch的repository。然後開啟滑鼠右鍵選單,選擇「Remote」中的Push
  2. 確認跳出的對話視窗的目標Repository是正確,然後按下Next
  3. 在中間的「Remote Ref to delete」,選擇想刪除的branch,然後按下「Add Spec」。確認該branch出現在「Specifications for push」中
  4. 然後繼續按下Next,出現Push Confirmation視窗,若一切正確,則按下Finsh,就會對Git Remote Repository送出;若無錯誤則完成刪除Remote branch。

2014年10月29日 星期三

如何重設Mac OSX的一些硬體相關設定

在使用MacBook Pro的日子裡,說實話從來也沒煩惱、也沒操作過有關於「BIOS」的東西,所以根本也不知道是否有類似的東西(Mac 後來改用Intel CPU後,好像也改用EFI的架構,跟BIOS不同,不過我也不太懂就是)。其實,老實說我個人也覺得這樣蠻好的,反正都由Mac OSX自己搞定就好。
不過有時也不是那麼美滿的,有時候可能在升級OS後會有點怪怪的,此時就可能要重設一下。主要的經驗就是本次升級OSX Yosemite的時候,在升級完後會出現一些怪怪的現象,最嚴重的就是Time Machine會變很慢甚至無回應,而且可能會造成無法正常關機或重開機,雖然有整個重灌,但是還是一樣。最後就是靠著重設硬體設定來搞定的。
怎麼重設呢?可以參考官方的步驟:重設電腦的PRAM

另外,有需要的時候也可進入所謂的「安全模式」:安全模式說明

註:PRAM是Apple 電腦的一個專用詞,好像是用來儲存跟跟硬體有關的設定

在Mac OSX啟用單鍵拖曳

從Mac OSX 10.9開始,內建的觸控版手勢就取消了單鍵拖曳的功能,改成用三指拖曳。不過我覺得不是那麼直覺好用,還是覺得單鍵拖曳好用。所幸,還是可以重新開啟此功能。
只要到「系統偏好設定」-->「輔助使用」-->「滑鼠與觸控式軌跡板」中,打開「觸控式軌跡板選項」,將「啟用拖移」打勾後,就可以在要拖曳的目標上用單指連點兩下後拖移。該選項還有設定:帶拖移鎖定、不帶拖移鎖定,主要是指拖移時如果放開手指,拖移鎖定是否仍然保留。若選擇「不帶拖移鎖定」,則放開後就解除,要再拖移,就得重新單指雙擊目標。



2014年10月27日 星期一

Java GC Tuning Guide episode 1 - GC logging

Java的GC讓開發人員減少處理記憶體配置的負擔,但是GC的運作方式與調整也關係到整個Java程式的運作效率與穩定性。先前一直有點半逃避的忽視這部份的東西,大都是用網路搜尋到的一些既有調整參數直接設了,不過該來的終究是要來,只靠一些別人的設定與調整方法,果然還是難以達到最佳的情況。要設定針對自己開發的程式/系統的最佳GC設定,還是得自己來追蹤與分析。

既然要自己追蹤與分析GC的情況,首先就必須有可以分析的資料,而最直接有用的就是GC log。以下說明如何透過JVM option啟用GC log來紀錄GC的內容:

  • -XX:+PrintGCDetails
    • 啟用此參數可讓JVM輸出所有詳細的GC行為,包含GC的類型(一般 or Full, Full GC會造成程式/系統暫停),以及JVM內各記憶體配置區塊的GC動作情況與耗費時間等,資訊相當完整。
  • -XX:+PrintGCTimeStamps 與-XX:+PrintGCDateStamps
    • 這兩個參數是讓JVM在輸出GC log時,也順便加上時間資訊;PrintGCTimeStamps 是以程式啟動時間的相對時間做紀錄,而PrintGCDateStamps則是以系統的絕對時間做紀錄。兩者可擇一或並存。加上時間紀錄有助於分析與判斷。
  • -Xloggc:<file name>
    • 預設啟用gc log時,是輸出到console上,但是這樣不便於閱讀與分析,所以此參數可以指定輸出到檔案上
  • -XX:+UseGCLogFileRotation
    • 使用上一個參數時,會將所有的gc log寫到同一個檔案。如果不想讓檔案不斷成長,可以使用此參數將gc log檔固定在一定數量大小。注意:使用此參數,也必須搭配以下兩個參數才能正確運作
  • -XX:NumberOfGCLogFiles=<number of files>
    • 指定要保留的gc log檔數量,預設為1
  • -XX:GCLogFileSize=<file size>
    • 指定要保留的單一gc log檔大小,預設512K,可用M or K指定大小,如128M。
設定好之後啟動程式,即可在指定檔案中存下完整的gc log。以下是gc log範例(注意:輸出格式可能因不同JVM版本而有所出入):
 0.011: [G1Ergonomics (Heap Sizing) expand the heap, requested expansion amount: 128974848 bytes, attempted expansion amount: 128974848 bytes]
2014-10-27T13:49:46.166+0800: 1.114: [GC pause (young) 1.114: [G1Ergonomics (CSet Construction) start choosing CSet, _pending_cards: 2283, predicted base time: 23.70 ms, remaining time: 176.30 ms, target pause time: 200.00 ms]
 1.114: [G1Ergonomics (CSet Construction) add young regions to CSet, eden: 14 regions, survivors: 0 regions, predicted young region time: 356.52 ms]
 1.114: [G1Ergonomics (CSet Construction) finish choosing CSet, eden: 14 regions, survivors: 0 regions, old: 0 regions, predicted pause time: 380.22 ms, target pause time: 200.00 ms]
, 0.0200610 secs]
   [Parallel Time: 13.7 ms, GC Workers: 4]
      [GC Worker Start (ms): Min: 1113.8, Avg: 1117.5, Max: 1123.2, Diff: 9.4]
      [Ext Root Scanning (ms): Min: 0.0, Avg: 1.3, Max: 2.8, Diff: 2.8, Sum: 5.3]
      [Update RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
         [Processed Buffers: Min: 0, Avg: 2.8, Max: 11, Diff: 11, Sum: 11]
      [Scan RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1]
      [Code Root Scanning (ms): Min: 0.0, Avg: 0.2, Max: 0.6, Diff: 0.6, Sum: 0.7]
      [Object Copy (ms): Min: 0.4, Avg: 5.6, Max: 10.8, Diff: 10.4, Sum: 22.6]
      [Termination (ms): Min: 0.0, Avg: 2.6, Max: 3.8, Diff: 3.8, Sum: 10.4]
      [GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1]
      [GC Worker Total (ms): Min: 4.1, Avg: 9.8, Max: 13.6, Diff: 9.5, Sum: 39.2]
      [GC Worker End (ms): Min: 1127.3, Avg: 1127.3, Max: 1127.5, Diff: 0.2]
   [Code Root Fixup: 0.3 ms]
   [Code Root Migration: 1.1 ms]
   [Clear CT: 0.1 ms]
   [Other: 4.8 ms]
      [Choose CSet: 0.0 ms]
      [Ref Proc: 4.6 ms]
      [Ref Enq: 0.0 ms]
      [Free CSet: 0.0 ms]
   [Eden: 14.0M(14.0M)->0.0B(15.0M) Survivors: 0.0B->2048.0K Heap: 14.0M(123.0M)->4084.5K(123.0M)]
 [Times: user=0.03 sys=0.01, real=0.02 secs] 
透過這些log資訊,就可以了解程式/系統運作時的gc行為,進而調整至最適合的設定。
當然,以人工方式來分析gc log,是很困難的,因此也有一些工具可以幫忙。 目前個人使用GCViewer來幫忙處理與分析,雖然不算是很完美,但是也幫了不少忙。

2014年7月16日 星期三

Ubuntu gnome-panel設定方式與注意事項

Ubuntu從11.10後續的新版的UI都改用Unity。如果不喜歡Unity,可以自行安裝gnome-panel與gnome-session來調整。但是後來新版的gnome-panel的設定方式與原本有些差異:
  • 設定:新版gnome-panel要設定的話,是不能直接在上頭按右鍵叫出選單的。必須按住鍵盤的Windows鍵+Alt,再按右鍵
  • 如果在增加與設定gnome-applet時,發生問題,可以用:
    dconf reset -f /org/gnome/gnome-panel/    
    來重設整個gnome-panel,不過此方法似乎只適用於Ubuntu 13.04之後
建議設定完畢後重新登入或是使用killall gnome-panel來重啟gnome-panel

2014年7月8日 星期二

JVM參數調教

官方的JDK裡的JVM已經越來越成熟,效能也越來越好,但是還是有可調教的空間。可調教的參數也跟著JDK演進而有所不同。根據網路上一些文章,大概比較普遍的調教參數有以下幾個:
  • -XX:+AggressiveOpts
  • -XX:+UseCompressedOops
  • -XX:+DoEscapeAnalysis
  • -XX:+UseBiasedLocking
  • -XX:+EliminateLocks
其中,第一個參數是用來調整一些預設的效能參數,啟用之後相當於調整了AutoBoxCacheMax, BiasedLockingStartupDelay, EliminateAutoBox, OptimizeFill, OptimizeStringComcat這幾個參數。第二個參數則是使用在64bit環境中,可以降低JVM在64-bit環境裡的記憶體使用量,並提升效能。後三個參數則是用來減少lock的使用情況,以提升效能。

另外還有一些參數也可能可以改善效能,但是因為沒有太多實務案例,所以無法100%肯定。
  • -XX:MaxGCPauseMillis:設定GC的暫停時間目標值,此數值可限制JVM的GC造成的暫停時間,但是無法精準限制。降低此數值可以減少JVM的延遲,但是可能會造成過多的GC與Throughput下降。
  • -XX:+UseG1GC:啟用JDK7以後新增加的G1GC功能,據說效果比原本的CMS好
  • -XX:+UseStringCache:就名稱來看應該是跟String有關的,但是實際效果不明,有人提過可搭配-XX:+PrintStringTableStatistics 和 -XX:StringTableSize=來調整StringCache大小
  • -XX:CompileThreshold=n:設定method在多少次呼叫後,轉換為機械碼。此數值越大,代表有越多profile資訊來轉換,可轉換出越高效率的機械碼。越低的話,代表越快進行轉換。JVM預設如果是client模式為1000,server模式為10000
  • -XX:+TieredCompilation:使用多層式的機械碼轉換方式。啟用此設定,可改設原本一次性轉換後的機械碼效率。在server模式預設啟用。
  • -XX:+UseLargePages:啟用Large Page的記憶體存取能力,需要OS支援。
  • -XX:MaxInlineSize=n:設定在n byte內的method會被用inline方式編譯,此數值越大,越能改善執行效率。但過大的數值會造成JVM的記憶體佔用過大。
  • -XX:ReservedCodeCacheSize=n:設定預設保留的CodeCache大小。當設定-XX:MaxInlineSize=n較大,或是-XX:CompileThreshold=n較小時,最好可以將此數值加大,否則可能會發生問題。
  • -XX:+UseCodeCacheFlushing:會將CodeCache進行清理,但實際上怎麼清理並不清楚。
  • -XX:+UseFastAccessorMethods, -XX:+UseFastEmptyMethods, -XX:+UseFastJNIAccessors:加速這些method的呼叫與執行
  • -Dawt.nativeDoubleBuffering=true:在GUI模式下,使用Double buffering來改善繪製效能
  • -Djava.net.preferIPv4Stack=true:讓JVM優先使用IPv4。可避免部分因IPv6造成的問題,以及改善連線效能。
  • -Djdk.map.althashing.threshold=n:啟用JDk7u6的新Hash function演算法,可改進效能。n值是指當Set或Map的大小達到時,才使用新演算法。若n=0,則表示強制使用新演算法。注意:新演算法可能造成在iterator順序上的改變(對LinkedHashSet與LinkedHashMap不造成影響)。
  • -XX:SoftRefLRUPolicyMSPerMB=n:指Soft Reference物件的生命週期。預設為1000ms,此數值設定越小,可加快Soft Reference物件被回收的速度。
以上是目前大略整理出的一些參數。上述參數的預設值可能因版本不同而有所不同。可以下列命令列出目前JVM支援的參數與預設值:
java -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version
或是
java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal -version (包含實驗性功能)
可另用pipeline將結果輸出至檔案。

以下是一些參考資料:

2013年5月27日 星期一

Redmine 效能改進

在公司的虛擬機上安裝的Bitnami Redmine stack一直在新增與更新issue時會有等待很長時間的問題。在搜尋了一下,研究了一下。有以下兩種解法,此兩種可同時搭配:

  • Phusion Passenger module的問題
  • email send的問題
    •  此問題是因為Redmine預設使用同步的email發送機制,所以當連線mail server需要時間較久或連不上時,就會導致整個回應變慢。解決方法就是在configuration.yml裡將原本的:smtp改為async_smtp即可。可參考:Asynchronous Email Delivery

以上作法在修改後都必須重新啟動Redmine

2013年4月22日 星期一

在Linux上啟用Tomcat JMX Remote之二三事

對於Tomcat要啟動JMX Remote的功能,只要遵照官網說明,在catalina.sh or catalina.bat設定系統參數就可以。
不過,在Linux上在啟用就麻煩多了。首先,在linux上可能無法正確的bind到正確的ip,所以如果發現設定後無法連上JMX MBean,就在catalina.sh中,多加一個系統參數
-Djava.rmi.server.hostname=<正確的host ip>
此處的ip不可為localhost或是127.0.0.1
如果Linux是有開防火牆的話,就會更麻煩。因為JMX預設的情況是會使用一個固定的port作為registry用,另外會再使用一個隨機的port作為service通訊用。registry用的port,可以透過系統參數指定,但是service通訊用的卻不行,所以在此情況下,是無法開通防火牆的。所幸,Tomcat有提供一個元件可以來設定。到Tomcat下載頁面下載Tomcat JMX Remote jar,並放到lib資料夾中,然後修改conf/server.xml,加入以下內容
<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener" rmiRegistryPortPlatform="10001" rmiServerPortPlatform="10002" />
,其中rmiRegistryPortPlatform就是指registry port, 而rmiServerPortPlatform就是指真正service通訊用的port

只要將這兩個port在防火牆中開通,就可以從外部來監控Tomcat了。

2012年11月12日 星期一

改變Ubuntu中使用者家目錄下的預設資料夾名稱

忘記從哪一版的Ubuntu開始,只要選擇安裝繁體中文版的Ubuntu,則使用者的家目錄(/home/[user id])裡的預設資料夾,如「影片」「圖片」等,都會以中文名稱建立...從GUI介面來操作可能還不是大問題,但是如果是從console操作,就變得很麻煩了....

之前版本的Ubuntu還可以透過更改語系(繁體中文<->英文)的方式,觸發一個GUI程式,詢問是否改變這些預設資料夾的名稱。只要先切換到英文語系,就會詢問是否改成英文名稱,此時選擇「是」;然後再切換回繁體中文語系,一樣會再次詢問,此時只要選擇「保留舊名稱」,就可以在繁體中文環境裡有英文的預設資料夾名稱了

但是這招在Ubuntu卻不管用了...還好透過Google search,找到解決方法,而且感覺也蠻簡單的。步驟如下:

  1. 打開console視窗,先使用以下指令確認目前語系:echo $LANG
  2. 然後輸入export LANG=en_US,將語系變更為「英文」
  3. 接著輸入xdg-user-dirs-gtk-update,此時就會出現前述所提到的GUI的資料夾更名程式,然後選擇「更名」,就可以將預設資料夾改為英文
  4. 完成更名後,在console視窗中輸入export LANG=[步驟1記下的語系設定],然後再做一次步驟3,此時要選擇「保留舊名稱」,這樣就大功告成了!

2012年9月7日 星期五

Mac OSX Mountain Lion 使用心得與小抱怨

上個月升級到mountain lion,感覺是還不錯。不過似乎偶爾還是會有怪怪的情況。最讓我不滿的是發生過兩次莫名其妙的畫面錯亂,以及一次的整個系統無反應,最後這兩種情況都只能透過強制硬體重開機來回復。

另外,一點讓我覺得很討厭的,是在部分軟體升級版本之後,在Finder右鍵選單中的「打開檔案的應用程式」,會出現重複的項目。一直覺得很困擾,但是終於找到解法了。
方法就是在「終端機」裡執行以下命令:

/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -kill -r -domain local -domain system -domain user

然後重啟Finder即可

不過對這次Mountain Lion其實還是有點失望,不是對功能失望,而是對穩定性方面感覺沒有之前Lion來的好。希望Apple再加油了!

2011年8月28日 星期日

JMX & Spring

用Spring要產生一個MBean並且註冊到MBeanServer是蠻容易的。基本上,幾乎只要使用XML設定就可以了。作法如下:
  1. 確定有使用context的XML schema。在XML設定檔中加入
    <context:mbean-server id="mbeanServer">
    , 其中id是用來表示該mbean server。這個xml tag是Spring 2.5以後多的,可以簡化設定。當然也可以用傳統的spring bean的定義方式:
    <bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean"/>
  2. 加入RMI registry的宣告,一般來說使用JMX的remoting,在沒特別處理的情況,都是以RMI protocol來做通訊:
    <bean id="rmiRegistry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean"><property name="port" value="1099"/></bean>
  3. 宣告MBean的connector server,這是用來讓外部可以連線到MBeanServer:
    <bean id="serverConnector" class="org.springframework.jmx.support.ConnectorServerFactoryBean">
    <property name="threaded" value="true"/>
    <property name="objectName" value="connector:name=rmi"/>
    <property name="serviceUrl" value="service:jmx:rmi://localhost/jndi/rmi://localhost:1099/jmxrmi"/>
    </bean>
    ,其中,service url的定義跟JMX的定義跟格式是一樣的。
  4. 最後就是宣告MBeanExporter,然後指定要export的bean跟ObjectName:
    <bean id="mbeanExporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
    <property name="server" ref="mbeanServer"/>
    <property name="registrationBehaviorName" value="REGISTRATION_REPLACE_EXISTING"/>
    <property name="beans">
    <map>
    <entry key="heero:name=msService" value-ref="mobileSuitService"/>
    </map>
    </property>
    </bean>
而連線的方式,可以用一般標準的JMX client連線方式,或是使用Spring的方式。Spring的方式就是透過MBeanProxyFactoryBean來產生MBean的proxy。
最後,有幾點注意:
  1. mbean server的宣告,如果不是使用<context:mbean-server/>,則如果再產生mbean server發現已經有同id的server存在時,還是會繼續產生。所以可能會造成混淆。所以必須額外加上
    <property name="locateExistingServerIfPossible" value="true"/>
  2. 在實際上使用發現,如果有使用Hibernate跟Spring JMX support,則用傳統bean定義的方式產生mbean server,會一直警告該server已經存在。
  3. 經測試發現,當mbean server啟動時,立刻去連線會失敗,但是若是等待幾秒則OK
  4. 根據Spring文件,MBeanExporter是不可以lazy initialization的。所以必須設定為lazy-init="false"
這是最簡單容易的作法之一,在幾乎不改code的情況下就可以產生JMX的支援。當然Spring也有其他的作法,像是使用annotation。詳情就參考Spring文件。

Property file & Spring

Spring設定除了透過annotation跟xml之外,也可以透過property file來讀取。SpringFramework有提供這樣的機制。
首先,定義設定檔內容,例如:
(jmx.properties)
jmx.host=localhost
jmx.port=1099

然後在spring的xml設定檔內,先加入PropertyPlaceholderConfigurer的定義:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jmx.properties"/>
</bean>
其中,location是指要讀取的設定檔檔名與位置。範例中的寫法是指在classpath內找尋jmx.properties。
然後在需要使用的spring xml設定檔中,使用${property name}的方式即可。例如:
<bean id="example" class="...">
<property name="host" value="${jmx.host}"/>
<property name="port" value="${jmx.port}"/>
</bean>

2011年2月16日 星期三

Objective-C的類別初始化

在Java中,要對class variable作初始化,可以透過static method或是static block;而在Objective-C則是必須透過initialize

在Objective-C中,物件的預設建構式為init,是用來對類別的單一物件作初始化。而除了這個method,其實還有另一個預設的初始化method,叫做"initialize"。這是一個static method,所以是針對class variable來做初始化的。

但是有幾點跟Java比較不同的:
  • Java的類別初始化,若是透過static method,則必須做明確的呼叫;但是Objective-C的initialize,則是會在該類別第一次載入時被自動呼叫(跟Java的static block較類似)。
  • Java的static block僅會被執行一次;Objective-C的initialize則是在父類別與子類別被載入時,會分別個執行一次。(若是實際上只有子類別被使用,則實際的載入動作會先載入父類別並執行initialize,然後再載入子類別與執行initialize
因此,在使用initialize應該特別注意是否會被子類別進行重複呼叫。解決方法是在initialize執行時,檢查當時的類別是否為父類別或是特定類別,範例程式如下:
+ (void)initialize {
if(self == [XXXX class]) {
// initialize class variables here
}
}
其中,XXXX指的是父類別名稱。

Create an UUID by using Objective-C

許多computer language都有方法可以產生UUID,所以Objective-C當然也不例外。目前查詢到而且驗證過可用的方法有兩種:
  • 使用C function:使用以下程式碼即可
- (NSString *)createUUID{
// Create universally unique identifier (object)
CFUUIDRef uuidObject = CFUUIDCreate(kCFAllocatorDefault);
// Get the string representation of CFUUID object.
NSString *uuidStr = [(NSString *)CFUUIDCreateString(kCFAllocatorDefault, uuidObject) autorelease];
CFRelease(uuidObject);
return uuidStr;
}

  • 使用NSProcessInfo 類別:使用以下程式碼即可
    NSString *uuid = [[NSProcessInfo processInfo] globallyUniqueString];
兩種方法都可以產生UUID,但是長度不一樣。NSProcessInfo因為參考比較多資訊來產生,所以產生的長度會比較長,為58個字元長度

Improve data upload speed on iPhone (for using ASIHTTPRequest)

在先前的文章就曾經介紹過使用在先前的文章就曾經介紹過使用ASIHTTPRequest來開發iOS上的HTTP通訊應用。它也的確讓coding變得比較簡單容易。不過,最近在實務上,卻碰到一個問題,就是當上傳大檔案或大量資料時,傳輸速率似乎不是很理想。經過一番股溝之後,發現在ASIHTTPRequest本身的API中,有相關設定可以改善。那就是透過static method
[ASIHTTPRequest setShouldThrottleBandwidthForWWAN:YES]
,來對流量作限制。事實上,該method的原意,似乎是在3G/GPRS網路下作流量管控的,不過API的說明也提到,對於大資料的上下傳也會有速度改善的效果。

但是,在不是很嚴謹的測試之後,發現該method的效果在大資料上傳才會比較明顯。對於下載,似乎不但沒有改善的效果,反而會減慢。而API文件也提到,使用該API應該盡量在需要的情況在開啟,否則平時應該是要設定在NO的狀態。但是,由於該method的設定效果是針對整個ASIHTTPRequest的,而非針對單一request物件,因此在不需要的情況下,必須明確的使用
[ASIHTTPRequest setShouldThrottleBandwidthForWWAN:NO]
來關閉功能。

2010年10月28日 星期四

Objective-C 之 日期字串格式化與轉換

在撰寫程式的時候,時常需要把日期物件跟它的字串表示式來做互轉的動作。在Java中,可以透過java.text.SimpleDateFormat來做。而在Objective-C中,也有類似的類別,叫做NSDateFormatter。

NSDateFormatter的用法其實很簡單,就是建立一個NSDateFormatter物件,然後設定需要的dateFormat。之後如果是要把日期物件轉換為字串表示法,則用stringFromDate:;反之,則是使用dateFromString:。詳細內容可以參考:Simple methods for date formatting and transcoding

2010年10月7日 星期四

Objective-C的@synchronized

在Objective-C中,也有synchronized這個keyword,也是用來作thread synchronization,正是語法是
@synchronized(id) { ... }
,其中id是只要鎖定的物件pointer。而比較常用的情況是
@synchronized(self)
有趣的是,如果@synchronized(self)語法出現在一般的instance method,則self是指該instance;但是如果是出現在static method,則self是指該class本身。

2010年9月26日 星期日

抱怨!Google的產品彼此支援度不佳....

剛剛在編輯blogger上的文章時,發現不管怎麼弄,文章內的style一直就是弄不好...最後,想到該不會是Google Chrome的問題吧...所以換到Safari 5.0.2再試一次,結果就OK了...........

其實不只這件,Chrome在某些HTML的呈現與layout效果,似乎也不是很正確,反而是Safari真的是比較正確一點,也比較沒有問題...要不是Safari的memory usage比較大,而且

這真的是一大諷刺啊...Google...