(# ゚Д゚) - 5-буквенное слово. Но в iOS длина [@"(# ゚Д゚)" равна 7. Почему?

(# ゚Д゚) - 5-буквенное слово. Но в iOS длина [@"(# ゚Д゚)" равна 7.

  1. Зачем?

  2. я использую <UITextInput> изменить текст в UITextField или же UITextView, Когда я делаю UITextRange длиной 5 символов, он может просто покрыть (# ゚Д゚). Итак, почему это (# ゚Д゚) выглядит как 5-символьное слово в UITextField а также UITextView, но выглядит как 7-символьное слово в NSString???

  3. Как я могу получить правильную длину строки в этом случае?

2 ответа

Решение

1) Как уже отмечалось в комментариях, ваша строка состоит из 5 составленных последовательностей символов (или кластеров символов, если вы предпочитаете). Когда разбито на unicharкак NSString"s length Метод вы получите 7, который является числом unichars требуется, чтобы представить вашу строку в памяти.

2) Видимо UITextField а также UITextView обрабатывают строки в Unichar хитрый способ. Хорошие новости, вы тоже можете. Смотрите № 3.

3) Вы можете получить количество составленных последовательностей символов, используя некоторые из NSString API, который правильно обрабатывает составленные последовательности символов. Быстрый пример, который я испек, очень быстро, это маленький NSString категория:

@implementation NSString (ComposedCharacterSequences_helper)
-(NSUInteger)numberOfComposedCharacterSequences{
    __block NSUInteger count = 0;
    [self enumerateSubstringsInRange:NSMakeRange(0, self.length)
                             options:NSStringEnumerationByComposedCharacterSequences
                          usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop){
                              NSLog(@"%@",substring); // Just for fun
                              count++;
                          }];
    return count;
}
@end

Опять же, это быстрый код; но это должно помочь вам начать. И если вы используете это так:

NSString *string = @"(# ゚Д゚)";
NSLog(@"string length %i", string.length);
NSLog(@"composed character count %i", [string numberOfComposedCharacterSequences]);

Вы увидите, что вы получите желаемый результат.

Для подробного объяснения NSString API проверить WWDC 2012 Session 215 Video "Text and Linguistic Analysis"

И то и другое а также Д゚ представлены последовательностью символов из двух символов Unicode (даже если они визуально представлены как один). -[NSString length] сообщает количество символов Unicode:

Возвращаемое число включает отдельные символы составленных последовательностей символов, поэтому вы не можете использовать этот метод, чтобы определить, будет ли строка отображаться при печати или как долго она будет появляться.

Если вы хотите увидеть байтовое представление:

#import <Foundation/Foundation.h>

NSString* describeUnicodeCharacters(NSString* str)
{
    NSMutableString* codePoints = [NSMutableString string];
    for(NSUInteger i = 0; i < [str length]; ++i){
        long ch = (long)[str characterAtIndex:i];
        [codePoints appendFormat:@"%0.4lX ", ch];
    }
    return codePoints;
}


int main(int argc, char *argv[]) {
    @autoreleasepool {
        NSString *s = @" ゚Д゚";
        NSLog(@"%ld unicode chars. bytes: %@", 
            [s length], describeUnicodeCharacters(s));
    }
}

Выход: 4 unicode chars. bytes: 0020 FF9F 0414 FF9F,

2) и 3): что сказал Джонс.

Другие вопросы по тегам