NSDictionary `description` problème de formatting – traite la structure comme des données de char

J'ai une class personnalisée (qui ressemble à un NSArray dans le concept et, espérons-le, l'apparence formatée) qui a un formateur de description .

Lorsque la sortie du formateur est imprimée (NSLog), elle semble correcte, mais lorsqu'elle est incluse comme élément d'une description NSDictionary, le formateur NSDictionary semble décider que c'est une string de caractères, pas une définition de structure, qui la place entre guillemets, et échappe tous les caractères de contrôle dans la string.

Cela ne se fait pas pour un NSArray standard, bien sûr, je me request donc comment il décide de traiter la string dans un sens ou dans l'autre.

Par exemple, plutôt que d'avoir une sortie qui ressemble à:

 theChildren = ( { "@meta.type" = "ns3:location"; "childNumber" = 0; ... 

Ça ressemble à:

 theChildren = "( \n\t\t {\n\t \"@meta.type\" = \"ns3:location\";\n\t \"childNumber\" = 0; ... 

Quelqu'un peut-il suggérer un moyen de modifier ce comportement?

FWIW, j'accumule la string de description (avec datatables consistant principalement des résultats des appels à la NSDictionary description ) dans un NSMutableSsortingng, puis fais NSSsortingng ssortingngFromSsortingng à la sortie (bien que je ne sache pas que cela fasse quoi que ce soit).

Ajoutée

Je pense que j'ai trouvé la réponse (je n'ai pas encore vérifié) enfouie dans l'écriture NSDictionary:

Discussion

L'object NSSsortingng renvoyé contient les représentations sous forme de string de chacune des inputs du dictionary. descriptionWithLocale: indent: obtient la représentation sous forme de string d'une key ou d'une valeur donnée comme suit:

 If the object is an NSSsortingng object, it is used as is. If the object responds to descriptionWithLocale:indent:, that 

La méthode est appelée pour get la représentation de string de l'object.

 If the object responds to descriptionWithLocale:, that method is 

invoqué pour get la représentation de string de l'object.

 If none of the above conditions is met, the object's ssortingng 

la représentation est obtenue en invoquant sa méthode de description.

Mettre à jour

Eh bien, il s'avère qu'ils mentent. J'ai implémenté descriptionWithLocale: indent: et il n'est jamais appelé.

Mise à jour 9/23

Fait intéressant, si je fais de ma class une sous-class de NSArray, alors NSDictionary appelle descriptionWithLocale: indent: et il formate correctement. On dirait que NSDictionary "sortingche" et que le test est " isKindOfClass plutôt que " isKindOfClass , ou que c'est juste un préjugé contre des choses non-NS.

C'est plutôt moche de devoir sous-classr NSArray, cependant, en termes d'acquisition de beaucoup de comportements que je ne veux pas imiter, et de transporter des données supplémentaires inutilisées.

Etc

Une autre option consiste à convertir la string échappée en son original. Cela prend une procédure de 31 lignes pour gérer les bases ( \n , \t , \" , et \\ ) Le côté positif est que je n'ai pas besoin de sous-classr NSArray, le principal inconvénient est que cette routine doit être inséré dans n'importe quel appel NSLog qui pourrait afficher ma class.Un autre inconvénient mineur est que les strings échappées ont été encapsulées avec des guillemets que je ne peux pas éliminer, mais c'est à peine perceptible.

J'ai le #ifdefed pour le moment – je ne sais pas ce que je vais choisir.

C'est une "fonctionnalité" merveilleuse liée à la security qui a été introduite dans la version OS X 10.5+ de syslog() .

Comme expliqué par un ingénieur Apple dans ce post: Qui a brisé NSLog sur Leopard? ,

C'est le comportement de syslog() . De la page de manuel:

Les returns à la ligne et autres caractères non imprimables incorporés dans la string de message sont imprimés dans un autre format. Cela empêche quelqu'un d'utiliser des caractères non imprimables pour build des messages de journal trompeurs dans un file de sortie. Les nouvelles lignes sont imprimées en "\ n", les tabs sont imprimés en "\ t". D'autres caractères de contrôle sont imprimés à l'aide d'une représentation caret ("^"), par exemple "^ M" pour le return chariot.

Le sous-système ASL, sur lequel NSLog () écrit, fait de même (au less dans Leopard). L'écriture du file XML dans un file est une alternative raisonnable.

Chris Kane Cocoa Frameworks, Apple

Voir man syslog pour plus d'informations.

Il n'y a pas de vraie réponse à cette question (la "caractéristique de security" d'OS X ne semble pas affecter les écritures de la console iOS), mais il y a ces deux solutions:

# 1: Fait intéressant, si je fais de ma class une sous-class de NSArray alors NSDictionary appelle descriptionWithLocale: indent: et il formate correctement. On dirait que NSDictionary "sortingche" et que le test est "KindOfClass" plutôt que "respondsToSelector", ou que c'est juste un préjugé contre des choses non-NS.

C'est plutôt moche de devoir sous-classr NSArray, cependant, en termes d'acquisition de beaucoup de comportements que je ne veux pas imiter, et de transporter des données supplémentaires inutilisées. Etc

# 2: Une autre option consiste à convertir la string échappée à son original. Cela prend une procédure de 31 lignes pour gérer les bases (\ n, \ t, \ ", et \.) L'inconvénient est que je n'ai pas besoin de sous-classr NSArray, le principal inconvénient est que cette routine doit être insérée Un autre inconvénient mineur est que les strings échappées ont été encapsulées avec des guillemets que je ne peux pas éliminer, mais c'est à peine perceptible.

(J'ai accepté cette réponse, même si ce n'est pas la "vraie" réponse, parce que mon% accepté souffrirait autrement Je pose trop de questions difficiles, je suppose.)