4

我已经观看了一些关于 Core Data 的 WWDC 视频,并且我计划维护一个规范化的文本属性。假设我有以下数据:

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

当我查询我的模型时,我想按“normalizedString”对其进行排序,以便它忽略大小写和 Ø(或其他字符)。我还希望能够运行“以'o'开头”之类的查询,并让它返回上面的 3 个单词。

我试图避免做类似的事情:

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

用于查询模型。我还尝试使用“originalString”进行排序。

我尝试了两种不同的方法都没有成功,我的规范化字符串仍然保存为 originalString(我在我创建的类别中覆盖了 setter):

  1. 调用 decomposedStringWithCanonicalMapping:

    // ...
    [normalizedString decomposedStringWithCanonicalMapping];
    // ...
    
  2. 按照这个例子

    // ...
    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"];
}
4

1 回答 1

0

您应该覆盖“主要”属性(例如firstName, lastName)的设置器,而不是“派生”属性的设置器。

另请注意,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;
}
于 2013-07-02T19:09:27.637 回答