NSDictionary`description`格式问题 – 处理类似char数据的结构
我有一个自定义的类(它类似于NSArray的概念,希望格式化的外观),它有一个description
格式化程序。
当格式化程序的输出本身被打印(NSLog)时,它看起来很好,但是当它作为NSDictionary description
的一个元素被包含时,NSDictionary格式程序似乎认为它是一个string,而不是一个结构定义,将它包含在引号中,并转义string中的所有控制字符。
当然,这对于一个标准的NSArray来说并不是这样,所以我想知道它是如何决定以一种方式处理string的。
例如,而不是输出如下所示:
theChildren = ( { "@meta.type" = "ns3:location"; "childNumber" = 0; ...
看起来像:
theChildren = "( \n\t\t {\n\t \"@meta.type\" = \"ns3:location\";\n\t \"childNumber\" = 0; ...
任何人都可以提出一种方法来改变这种行为?
FWIW,我在NSMutableString中累积了描述string(主要由调用NSDictionary description
的结果组成的数据),然后在出口处做NSString stringFromString
(尽pipe我不知道那是干什么的)。
添加
我想我find了埋在NSDictionary文件中的答案(还没有检查):
讨论
返回的NSString对象包含每个字典条目的string表示forms。 descriptionWithLocale:indent:如下所示获取给定键或值的string表示forms:
If the object is an NSString object, it is used as is. If the object responds to descriptionWithLocale:indent:, that
方法被调用以获取对象的string表示。
If the object responds to descriptionWithLocale:, that method is
调用来获取对象的string表示。
If none of the above conditions is met, the object's string
表示是通过调用其描述方法获得的。
更新
那么,原来他们在撒谎。 我实现了descriptionWithLocale:indent:它永远不会被调用。
更新9/23
有趣的是,如果我把我的类作为NSArray的子类,那么NSDictionary调用descriptionWithLocale:indent:并正确地格式化。 听起来像NSDictionary是“作弊”和testing是isKindOfClass
而不是respondsToSelector
,否则只是对非NS的东西偏见。
然而,要获得NSArray的子类是很丑陋的,因为它获得了许多我不想模仿的行为,并且带有额外的未使用的数据。
等等
另一个select是将转义的string转换回原来的string。 这需要一个31行的程序来处理基本的( \n
, \t
, \"
和\\
)。另一方面,我不需要NSArray的子类。主要的缺点是这个例程必须插入任何可以显示我的类的NSLog调用。另一个小缺点是逃逸的string被引用字符包装,我不能消除,但这并不明显。
现在得到它#ifdefed – 不知道我会select。
这是在OS X 10.5+版本的syslog()
引入的一个很好的安全相关的“特性”。
正如苹果工程师在这篇文章中解释的那样: NSLog是谁打破了Leopard? ,
这就是
syslog()
的行为。 从手册页:embedded在消息string中的换行符和其他不可打印的字符以另一种格式打印。 这可以防止某人使用不可打印的字符在输出文件中构造误导性的日志消息。 换行符打印为“\ n”,标签打印为“\ t”。 其他控制字符使用加号(“^”)表示打印,例如“^ M”用于回车。
NSLog()写入的ASL子系统也是这样(至less在Leopard中)。 将XML写入文件是一个合理的select。
克里斯凯恩cocoa框架,苹果
有关更多信息,请参阅man syslog
。
这个问题没有真正的答案(OS X的“安全function”似乎不影响iOS控制台写入),但有两个解决方法:
#1:有趣的是,如果我把我的类作为NSArray的子类,则NSDictionary调用descriptionWithLocale:indent:并正确格式化。 听起来像NSDictionary是“作弊”和testing是KindOfClass而不是respondsToSelector,否则只是对非NS的东西偏见。
然而,要获得NSArray的子类是很丑陋的,因为它获得了许多我不想模仿的行为,并且带有额外的未使用的数据。 等等
#2:另一种select是将转义的string转换回原来的string。 这需要一个31行程序来处理基本的(\ n,\ t,\“和\)。另一方面,我不需要NSArray的子类,主要的缺点是必须插入这个例程在任何可以显示我的类的NSLog调用中,另一个小缺点是逃逸的string被引用字符包装,我不能消除,但是这是不明显的。
(接受这个答案,即使它不是“真正”的答案,因为我接受的%会受到其他的影响,我想问太多难题。