2013-02-18 16 views
6

(# ゚ Д ゚) è una parola di 5 lettere. Ma in iOS, [@ "(# ゚ Д ゚)" lunghezza] è 7.(# ゚ Д ゚) è una parola di 5 lettere. Ma in iOS, [@ "(# ゚ Д ゚)" lunghezza] è 7. Perché?

  1. Perché?

  2. Sto usando <UITextInput> per modificare il testo in un UITextField o UITextView. Quando creo un UITextRange di 5 caratteri, può solo coprire il (# ゚ Д ゚). Quindi, perché questo (# ゚ Д ゚) sembra una parola di 5 caratteri in UITextField e UITextView, ma sembra una parola di 7 caratteri in NSString ???

  3. In che modo è possibile ottenere la lunghezza corretta di una stringa in questo caso?

+0

Ad una ipotesi, direi codifica dei caratteri: NSString conta il numero di byte rispetto al numero di caratteri? forse 2 dei tuoi personaggi sono in realtà caratteri multi-byte, e NSString scatta ... come detto, questa è una supposizione – AndrewP

+0

(# ゚ Д ゚) ha 7 caratteri se la copi e la incolli in un editor di testo. – Bahamut

+2

"Sembra" una parola di 6 caratteri perché c'è uno spazio alla fine. Tuttavia "Д ゚" è in realtà due caratteri in unicode. – borrrden

risposta

7

1) Come molti nei commenti hanno già detto, La stringa è fatto di 5 sequenze di caratteri composte (o cluster di caratteri, se si preferisce). Quando si analizza per unichar s come il metodo NSString di length si ottiene un 7 che corrisponde al numero di unichar s necessario per rappresentare la stringa in memoria.

2) A quanto pare la UITextField e UITextView sono la manipolazione del corde in modo esperto UNICHAR. Buone notizie, anche tu puoi. Vedi # 3.

3) È possibile ottenere il numero di sequenze di caratteri composte utilizzando alcune delle API NSString che gestiscono correttamente le sequenze di caratteri composte. Un esempio veloce ho cotto up, molto rapidamente, è un piccolo NSString categoria:

@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 

Anche in questo caso è il codice rapido; ma dovrebbe iniziare. E se lo usi in questo modo:

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

Vedrai che ottieni il risultato desiderato.

Per una spiegazione dettagliata della NSString API controllare il WWDC 2012 Session 215 Video "Text and Linguistic Analysis"

1

Sia e Д゚ sono rappresentati da un character sequence di due caratteri Unicode (anche quando sono presentati visivamente come uno). -[NSString length] riporta il numero di caratteri Unicode:

Il numero restituito include i singoli caratteri di composti sequenze di caratteri, in modo da non è possibile utilizzare questo metodo per determinare se una stringa sarà visibile quando vengono stampate o quanto tempo ci compaiono.

Se volete vedere la rappresentazione di byte:

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

L'output è: 4 unicode chars. bytes: 0020 FF9F 0414 FF9F.

2) e 3): cosa hanno detto NJones.