我有一个自定义类(类似于NSArray的概念,希望是格式化的外观),它有一个description
格式化程序。
当格式化程序的输出本身打印(NSLog)时它看起来很好,但当它作为NSDictionary description
的元素包含时,NSDictionary格式化程序似乎决定它是一个字符串,而不是一个结构definition,用引号括起来,并转义字符串中的所有控制字符。
当然,对于标准的NSArray,它不会这样做,所以我想知道它是如何决定将字符串单向处理的。
例如,不要让输出看起来像:
theChildren = (
{
"@meta.type" = "ns3:location";
"childNumber" = 0;
...
看起来像:
theChildren = "( \n\t\t {\n\t \"@meta.type\" = \"ns3:location\";\n\t \"childNumber\" = 0;
...
有人可以提出改变这种行为的方法吗?
FWIW,我在NSMutableString中累积描述字符串(数据主要由调用NSDictionary description
的结果组成),然后在出口处NSString stringFromString
(虽然我不知道那个)什么都做。)
我想我找到了NSDictionary写作中的答案(尚未检查):
讨论
返回的NSString对象包含字符串表示形式 每个字典的条目。 descriptionWithLocale:缩进: 获取给定键或值的字符串表示形式,如下所示:
调用If the object is an NSString object, it is used as is. If the object responds to descriptionWithLocale:indent:, that
方法来获取对象的字符串表示。
If the object responds to descriptionWithLocale:, that method is
被调用以获取对象的字符串表示。
If none of the above conditions is met, the object’s string
表示是通过调用其描述方法获得的。
好吧,原来他们说谎了。我实现了descriptionWithLocale:indent:它永远不会被调用。
有趣的是,如果我使我的类成为NSArray的子类,那么NSDictionary会调用descriptionWithLocale:indent:并且它正确格式化。听起来像NSDictionary是“作弊”并且测试isKindOfClass
而不是respondsToSelector
,否则就会对非NS的东西产生偏见。
但是,在获取许多我不想模仿的行为和携带额外未使用的数据方面,必须继承NSArray是一种丑陋。
另一种选择是将转义后的字符串转换回原始字符串。这需要一个31行程序来处理基础知识(\n
,\t
,\"
和\\
)。从好的方面来说,我不需要继承NSArray。主要缺点是必须在任何可以显示我的类的NSLog调用中插入此例程。另一个小的缺点是逃脱的字符串上写着我无法消除的引号字符,但这几乎不可察觉。
现在得到#ifdefed - 不确定我会选择哪个。
答案 0 :(得分:5)
这是一个与安全相关的精彩“功能”,已在OS {10.5}版syslog()
中引入。
正如本文中的Apple工程师所解释的那样:Who broke NSLog on Leopard?,
这是
syslog()
的行为。从手册页:消息中嵌入的换行符和其他不可打印字符 字符串以其他格式打印。这可以防止有人来 使用不可打印的字符来构造误导性日志 输出文件中的消息。换行符打印为“\ n”,标签打印为 “\ t” 的。其他控制字符使用插入符号打印(“^”) 表示,例如“^ M”用于回车。
NSLog()写入的ASL子系统也是如此(至少在 豹)。将XML写入文件是一种合理的选择。
Chris Kane Cocoa Frameworks,Apple
有关详细信息,请参阅man syslog
。
答案 1 :(得分:2)
这个问题没有真正的答案(OS X的“安全功能”似乎不会影响iOS控制台写入),但有两种解决方法:
#1:有趣的是,如果我将我的类作为NSArray的子类,那么NSDictionary会调用descriptionWithLocale:indent:并且它正确格式化。听起来像NSDictionary是“作弊”而且测试是isKindOfClass而不是respondsToSelector,否则只是对非NS的东西有偏见。
然而,在获取许多我不想模仿的行为以及携带额外的未使用数据方面,必须继承NSArray是一种丑陋。 等#2:另一种选择是将转义后的字符串转换回原始字符串。这需要一个31行程序来处理基础知识(\ n,\ t,\ t \,和\)。最重要的是我不需要子类化NSArray。主要缺点是必须插入此例程在任何可以显示我的类的NSLog调用中。另一个小的缺点是转义的字符串包含了我无法消除的引号字符,但这几乎不可察觉。
(接受这个答案,即使这不是“真正的”答案,因为我接受的%会受到影响。我想我会问太多疑难问题。)