2011年2月16日 星期三

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...

Singleton pattern for Objective-C

在Java中,要撰寫一個應用Singleton pattern的class十分容易。但是在Objective-C中,就沒這麼簡單了。原因在於物件與記憶體的配置與管理機制是完全不同的(個人見解,不見得對)。

其實原理是都很類似,就是設法讓app只產生一個object instance,而且是透過特定的static method來獲得這個instance,而不是透過constructor來建立各個獨立的instance。對於一些某些需要集中管理的資訊或是資源,singleton pattern十分有用。

在Objective-C中,因為無法宣告constructor為private,所以很難避免使用者去呼叫。另外,因為Objective-C的alloc/retain/release/dealloc的機制,所以我們也必須去處理有關instance reference count的問題,不然很容易會出現記憶體管理的問題...而造成災難。

如何撰寫呢?首先,先在header file中定義要取得singleton instance的static method,例如:
+ (id) sharedInstance;
然後,在對應的.m檔案中,添加下列內容:
static MyManager *instance = nil;

@implementation MyManager

#pragma mark Singleton Methods
+ (id)sharedInstance {
@synchronized(self) {
if(sharedMyManager == nil)
sharedMyManager = [[super allocWithZone:NULL] init];
}
return sharedMyManager;
}

+ (id)allocWithZone:(NSZone *)zone {
return [[self sharedManager] retain];
}

- (id)copyWithZone:(NSZone *)zone {
return self;
}

- (id)retain {
return self;
}

- (unsigned)retainCount {
return UINT_MAX; //denotes an object that cannot be released
}

- (void)release {
// never release
}

- (id)autorelease {
return self;
}

- (id)init {
if (self = [super init]) {
// initialize your instance variables
}
return self;
}

- (void)dealloc {
// Should never be called, but just here for clarity really.
// release your instance variables
[super dealloc];
}
@end
首先,是定義全域變數instance,用來表示此class的singleton instance。然後實作之前定義的singleton method,讓它傳回該instance variable,如此一來,只要呼叫此method,就可以取得同一個instance。其他的method都是override原本NSObject的定義。主要是用來處理reference count的問題,用來避免該instance被不小心release掉。其中,在init跟dealloc,可以對自己定義的instance variables做初始化跟回收。原則上,Objective-C的singleton pattern大概就是長這樣。

心得:比起Java,真的複雜多了...而且老實說,我也不知道這樣想是不是真的沒問題...只是目前google到的寫法,大多是長得類似這樣。