2013-02-05 16 views
11

sto correndo il seguente codice nella funzione viewDidLoad di una vaniglia iPad un'unica vista app:Perché a volte NSLog stampa ottale per caratteri ucode?

/* 
* Print the string. A lot. 
*/ 
for (int i = 0; i < 300; i++) { 
    NSLog(@"%d\n", i); 
    NSLog(@"⊢ ⊣ ⊥ ⊻ ⊼ ⊂ ⊃ ⊑ ⊒ \n"); 
} 

L'output è simile al seguente:

2013-02-04 20:17:49.718 testplay[59585:c07] 228 
2013-02-04 20:17:49.718 testplay[59585:c07] ⊢ ⊣ ⊥ ⊻ ⊼ ⊂ ⊃ ⊑ ⊒ 
2013-02-04 20:17:49.719 testplay[59585:c07] 229 
2013-02-04 20:17:49.719 testplay[59585:c07] ⊢ ⊣ ⊥ ⊻ ⊼ ⊂ ⊃ ⊑ ⊒ 
2013-02-04 20:17:49.719 testplay[59585:c07] 230 
2013-02-04 20:17:49.720 testplay[59585:c07] ⊢ ⊣ ⊥ ⊻ ⊼ ⊂ ⊃ ⊑ ⊒ 
2013-02-04 20:17:49.720 testplay[59585:c07] 231 
2013-02-04 20:17:49.720 testplay[59585:c07] ⊢ ⊣ ⊥ ⊻ ⊼ ⊂ ⊃ \342\212\221 ⊒ 
2013-02-04 20:17:49.723 testplay[59585:c07] 232 
2013-02-04 20:17:49.724 testplay[59585:c07] ⊢ ⊣ ⊥ ⊻ ⊼ ⊂ ⊃ ⊑ ⊒ 

L'ottale avviene quasi sempre lo stesso carattere e il singhiozzo si verifica casualmente circa 3 volte per corsa.

Mentre è relativamente innocuo in NSLog(), implica che i caratteri Unicode possono essere trattati in modo irregolare a un certo livello. Se c'è una storia per questo comportamento o qualche risorsa che potrei guardare sarebbe grandiosa.

[addendum: rimosso il riferimento a come mi sono imbattuto in questo problema. Capire come e perché NSLog ottiene una lettura corrotto di un carattere Unicode è la mia speranza qui]

+0

Il comportamento di NSLog è interessante (e riproducibile). Tuttavia, la modifica del codice per confrontare le iterazioni non causa stringhe non corrispondenti. Sarebbe utile se tu pubblicassi il metodo di confronto che in realtà causa i tuoi problemi ('confronta:', 'isEqualToString:', 'compare: options:', etc) –

risposta

8

Versione corta:.

Penso che questo accade se una sequenza UTF-8 di un NSLog() uscita succede cadere sul limite del buffer dello pseudo-terminale che Xcode utilizza per l'errore standard del processo di debug.

Se la mia ipotesi è corretta, questo è solo un problema dell'output del debugger Xcode e non implica alcun problema Unicode nell'applicazione.

Versione lunga:

Se si esegue la vostra applicazione nel simulatore, lsof -p <pid_of_simulated_app> mostra che l' errore (descrittore di file 2) standard viene reindirizzato a una pseudo-terminale:

# lsof -p 3251 
... 
testplay 3251 martin 2w  CHR    16,2  0t131  905 /dev/ttys002 
... 

E lsof -p <pid_of_Xcode> mostra che Xcode ha lo stesso pseudo-terminale aperto:

# lsof -p 3202 
... 
Xcode 3202 martin 51u  CHR    16,2  0t0  905 /dev/ttys002 
... 

NSLog() scrive su errore standard. Con il system call tracer "dtruss" si può vedere che Xcode legge il messaggio di log dallo pseudo-terminale. Per un singolo messaggio di log

NSLog(@"⊢ ⊣ ⊥ ⊻ ⊼ ⊂ ⊃ ⊑ ⊒ \n"); 

sembra che questo:

# dtruss -n Xcode -t read_nocancel 
3202/0xe101: read_nocancel(0x31, "2013-02-05 08:57:44.744 testplay[3251:11303] \342\212\242 \342\212\243 ... \342\212\222 \n\0", 0x8000)  = 82 0 

Ma per molte NSLog() dichiarazioni si susseguono rapidamente, a volte accade quanto segue:

# dtruss -n Xcode -t read_nocancel 
... 
3202/0xd828: read_nocancel(0x33, "2013-02-05 08:39:51.156 ...", 0x8000) = 1024 0 
3202/0xd87b: read_nocancel(0x33, "\212\273 \342\212\274 ...", 0x8000) = 24 0 

Come si può vedere , Xcode ha letto 1024 byte dallo pseudo-terminale e la successiva lettura inizia con una sequenza UTF-8 incompleta. In questo caso, Xcode "non vede" che l'ultimo byte della prima lettura e i primi due byte della seconda lettura sono parti della sequenza stessa UTF-8. Presumo che Xcode consideri tutti i 3 byte come sequenze UTF-8 non valide e li stampa come numeri ottali.

+0

Questa è una spiegazione molto convincente. Non spiega del tutto perché di solito è lo stesso personaggio, ma penso che possa essere tranquillamente colto fino ai capricci del buffering e del timing dei processi. Grazie! –

0

Una soluzione, nel tuo ciclo, inserisci un "fflush (stderr);" dopo la seconda dichiarazione NSLog; Questo costringerà lo stderr a commettere e scrivere il buffer prima di continuare.