2008年5月21日 星期三

使用CoreData的小技巧

上個月在參加過CocoaHeades後,自己也試著使用CoreData。
雖然在現場藍兄講得清楚明白又容易,自個兒嘗試使用卻不是那麼回事。
果然是看人挑擔不吃力,自個兒挑擔壓斷肩...

在使用CoreData時,個人覺得比較麻煩的是,CoreData的說明文件似乎已預設開發者都對資料庫的設計有一定的基礎,所以並沒有提到一些基本的資料庫程式的原則-像是怎麼規劃,如何做正規化,Data Model的圖怎麼對應到實際的資料庫與呈現的介面之上? 除此之外,其他的地方照著文件一步步進行,也還算是輕鬆如意。


不過在使用Data Model設計完資料庫,並加以正規化後,在實作資料類別時,發生了一個小問題,在正規化的過程中,我設計了一個ID欄位,這個欄位的值在每一筆資料中都必需是獨一無二的。為了要讓這個值不重複,最簡單的作法是每增加一筆資料,就將這個值加1。在Apple的範例中,也是這麼做的:
程式碼:


- (void)awakeFromInsert
{
static int tempID = 1;
[super awakeFromInsert];
self.employeeID = [NSNumber numberWithInt:tempID++];

}

不過這樣的做法,在實際使用上會有些問題:
當我把現有的文件存檔後,關閉程式再載入時,此時新加入的資料,其ID又會從頭開始計算。顯然的,這種做法並不符合實際使用的需求。
因此,我在此手法上,稍微做了點擴充:
程式碼:

static int tempID = 1;
- (void)awakeFromInsert
{
[super awakeFromInsert];
self.employeeID = [NSNumber numberWithInt:tempID++];
}

- (void)awakeFromFetch
{
[super awakeFromFetch];
if([self.employeeID intValue] >= tempID)
tempID = [self.employeeID intValue]+1;

}


從初步的結果看來,這種做法是可行的,每當我讀取檔案時,awakeFromFetch會被喚起,並找到目前最大的ID值。之後在增加新的資料時,ID就會以目前資料庫的最大值為基礎,逐步增加。

除了上面的awakeFromInsert,暨awakeFromFetch外,我們還必須加上下面這段:
程式碼:

- (void)didTurnIntoFault
{
tempID = 0;
[super didTurnIntoFault];

}

不然的話,當我們關掉前一份資料庫,並產生一份新資料庫時,tempID會延用之前的最大值,而非重置為0。

這是目前我想到最簡單的做法,只是不知有沒有更適合的做法?

沒有留言: