2013-07-02 83 views
4

我已經觀看了Core Data上的一些WWDC視頻,並且計劃維護一個規範化的文本屬性。 比方說,我有以下數據:爲核心數據規範化或規範化字符串?

originalString    normalizedString (+lowercase?) 
Ønsker      onsker 
onsker      onsker 
Onsker      onsker 

當我詢問我的模型,我想通過「規格化」進行排序,以便它忽略的情況和O(或其它字符)。我也希望能夠運行一個查詢,如「開始於'o'」,並讓它返回上面的3個單詞。

我試圖避免做一些事情,如:查詢模型

[NSPredicate predicateWithFormat:@"(originalString like[cd] %@)"... 

。 我也在嘗試爲我的排序使用'originalString'。

我試過沒有成功兩種不同的方法,我的規範化字符串仍然保存爲originalString(我重寫我創建了一個類的setter):

  1. 調用decomposedStringWithCanonicalMapping:

    // ... 
    [normalizedString decomposedStringWithCanonicalMapping]; 
    // ... 
    
  2. 其次this example

    // ... 
    CFStringNormalize((CFMutableStringRef)normalizedString, kCFStringNormalizationFormD); 
    CFStringFold((CFMutableStringRef)normalizedString, kCFCompareCaseInsensitive | kCFCompareDiacriticInsensitive | kCFCompareWidthInsensitive, NULL); 
    

關於如何完成我的目標的任何想法?

編輯: 這是我重寫的二傳手,我知道它被稱爲:

- (void) setNormalizedName:(NSString *)newNormalizedName 
{ 
    NSMutableString *normalizedString; 
    if (![self.lastName length] == 0) { 
     normalizedString = [NSMutableString stringWithString:self.lastName]; 
    } else { 
     normalizedString = [NSMutableString stringWithString:self.firstName]; 
    } 

// CFStringNormalize((CFMutableStringRef)normalizedString, kCFStringNormalizationFormD); 
// CFStringFold((CFMutableStringRef)normalizedString, kCFCompareCaseInsensitive | kCFCompareDiacriticInsensitive | kCFCompareWidthInsensitive, NULL); 
    [normalizedString decomposedStringWithCanonicalMapping]; 

    [self willChangeValueForKey:@"normalizedName"]; 
    [self setPrimitiveValue:normalizedString forKey:@"normalizedName"]; 
    [self didChangeValueForKey:@"normalizedName"]; 
} 
+0

請出示您的自定義setter方法的代碼。我不明白爲什麼這不應該工作。 –

+0

@MartinR我編輯了我的問題以包含我的setter方法。 – Eric

回答

0

您應該重寫setter方法「主」的特性(例如firstNamelastName),而不是引領者「派生」財產。

另請注意,decomposedStringWithCanonicalMapping返回一個新字符串,它不會 修改接收器。

代碼可以大致是這樣的(未編譯器檢查):

- (void) setFirstName:(NSString *)firstName 
{ 
    [self willChangeValueForKey:@"firstName"]; 
    [self setPrimitiveValue:firstName forKey:@"firstName"]; 
    [self didChangeValueForKey:@"firstName"]; 
    [self updateNormalizedName]; 
} 

- (void) setLastName:(NSString *)lastName 
{ 
    [self willChangeValueForKey:@"lastName"]; 
    [self setPrimitiveValue:lastName forKey:@"lastName"]; 
    [self didChangeValueForKey:@"lastName"]; 
    [self updateNormalizedName]; 
} 

- (void) updateNormalizedName 
{ 
    NSString *normalizedString; 
    if ([self.lastName length] > 0) { 
     normalizedString = [self.lastName decomposedStringWithCanonicalMapping]; 
    } else { 
     normalizedString = [self.firstName decomposedStringWithCanonicalMapping]; 
    } 
    self.normalizedString = normalizedString; 
} 
+0

這就是我想要做的,但我重寫setFirstName,setLastName和setNormalizedName,所以我可能在那裏創建了一個問題。我會再次嘗試使用這個新方法'updateNormalizedName'。一旦我開始測試,我會將您的答案標記爲正確。 – Eric

+0

我試着做你所建議的,但decomposedStringWithCanonicalMapping返回相同的字符串。我添加了上面的註釋行,但只是將Ønsker轉換爲ønsker。我希望讓恩斯克能夠成爲現實。 任何想法? – Eric

+0

@Eric:正如我現在看到的,我的答案更關注「如何爲規範化屬性編寫setter」,但這並不能解決「如何規範化Øto o」的具體問題。 - 這可能是後者是不可能的,比較http://stackoverflow.com/questions/16836975/ios-cfstringtransform-和類似的問題和http://stackoverflow.com/questions/9376621/folding-normalizing-爲了可能的解釋,可以使用連字 - 例如-ea-using-corefoundation。 –