为Core Data标准化或Canonicalize字符串?

时间:2013-07-02 06:03:12

标签: iphone ios objective-c core-data

我在核心数据上观看了一些WWDC视频,我正计划维护一个规范化的文本属性。 假设我有以下数据:

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

当我查询我的模型时,我想通过'normalizedString'对其进行排序,以便它忽略大小写和Ø(或其他字符)。我还希望能够运行像“以'开头''这样的查询并让它返回上面的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);
    
  3. 关于如何实现目标的任何想法?

    编辑: 这是我被覆盖的setter,我知道它被称为:

    - (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"];
    }
    

1 个答案:

答案 0 :(得分:0)

您应该覆盖“主要”属性的设置者(例如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;
}