2013-02-18 6 views
6

(# ゚ Д ゚) to 5-literowe słowo. Ale w systemie iOS [@ "(# ゚ Д ゚)" długość] wynosi 7.(# ゚ Д ゚) to 5-literowe słowo. Ale w systemie iOS [@ "(# ゚ Д ゚)" długość] wynosi 7. Dlaczego?

  1. Dlaczego?

  2. Używam <UITextInput> do modyfikacji tekstu w UITextField lub UITextView. Kiedy utworzę UITextRange o długości 5 znaków, może on po prostu pokryć (# ゚ Д ゚). Dlaczego to (# ゚ Д ゚) wygląda jak 5-znakowe słowo w UITextField i UITextView, ale wygląda jak 7-znakowe słowo w NSString?

  3. Jak w takim przypadku uzyskać prawidłową długość napisu?

+0

na oko, powiedziałbym kodowanie znaków - liczy NSString liczbę bajtów vs liczby znaków? może 2 z twoich bohaterów są faktycznie znaków wielo-bajtowych i NSString wycieczki do ... jak stwierdził, że to przypuszczenie – AndrewP

+0

(# ゚ Д ゚) ma 7 znaków, jeśli skopiować i wkleić go w edytorze tekstowym. – Bahamut

+2

"Wygląda jak" sześcioznakowe słowo, ponieważ na końcu jest spacja. Jednak "Д ゚" jest w rzeczywistości dwoma znakami w Unicode. – borrrden

Odpowiedz

7

1) Aż w komentarzach już wspomniano, Twój napis jest wykonany z 5 złożonych sekwencji znaków (lub klastrów charakter, jeśli wolisz). Po podziale według unichar s jako metoda NSString otrzymuje numer 7, który jest numerem unichar, który reprezentuje ciąg w pamięci.

2) Widocznie UITextField i UITextView obchodzenia sznurki w zrozumiały sposób o unichar. Dobra wiadomość, więc możesz. Zobacz # 3.

3) Można uzyskać liczbę złożonych sekwencji znaków za pomocą niektórych NSString API, która zajmuje się prawidłowo skomponowanych sekwencji znaków. Szybki przykład upiekłam się bardzo szybko, to mały NSString kategoria:

@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 

Znowu jest to szybki kod; ale powinno zacząć. A jeśli użyjesz go tak:

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

Zobaczysz, że uzyskasz pożądany rezultat.

o wyjaśnienie w dogłębne NSString API sprawdzeniu WWDC 2012 Session 215 Video "Text and Linguistic Analysis"

1

Zarówno i Д゚ są reprezentowane przez character sequence z dwóch znaków Unicode (nawet gdy są one prezentowane jako jeden wizualnie). -[NSString length] raportuje liczbę znaków Unicode:

Liczba powrócił obejmuje poszczególne znaki składające sekwencje znaków, więc nie można użyć tej metody, aby ustalić, czy ciąg będą widoczne po wydrukowaniu lub jak długo to będzie pojawia się.

Jeśli chcesz zobaczyć reprezentację bajtów:

#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)); 
    } 
} 

wyjście jest: 4 unicode chars. bytes: 0020 FF9F 0414 FF9F.

2) i 3): co powiedział NJones.

Powiązane problemy