Objective c 诸如“%15@”之类的格式说明符适用于NSLog,但不适用于NSString stringWithFormat

Objective c 诸如“%15@”之类的格式说明符适用于NSLog,但不适用于NSString stringWithFormat,objective-c,nslog,format-specifiers,stringwithformat,Objective C,Nslog,Format Specifiers,Stringwithformat,尝试将宽度说明符与%@一起使用时,我发现了一些奇怪的情况。它们在NSLog中可以正常工作,但在nsstringwithformat:中不能正常工作 例如: NSString *rightAligned = @"foo"; NSString *leftAligned = @"1"; NSLog(@"| %15@ | %-15@ |", rightAligned, leftAligned); 您将获得以下预期输出: | foo | 1 | 但

尝试将宽度说明符与
%@
一起使用时,我发现了一些奇怪的情况。它们在
NSLog
中可以正常工作,但在
nsstringwithformat:
中不能正常工作

例如:

NSString *rightAligned = @"foo";
NSString *leftAligned = @"1";

NSLog(@"| %15@ | %-15@ |", rightAligned, leftAligned);
您将获得以下预期输出:

|             foo | 1               |
但将
NSLog
替换为
stringWithFormat:

NSString *test = [NSString stringWithFormat:@"| %15@ | %-15@ |", rightAligned, leftAligned];
test
的值不正确:

| foo | 1 |
如果我将其更改为使用
%s
cStringUsingEncoding:
,则它可以工作:

NSString *test2 = [NSString stringWithFormat:@"| %15s | %-15s |", [rightAligned cStringUsingEncoding:NSUTF8StringEncoding], [leftAligned cStringUsingEncoding:NSUTF8StringEncoding]];
结果与
NSLog
的结果相同

真正奇怪的是,
NSLog
基本上只是
nsstringwithformat:
的包装器

那么为什么会有不同的结果呢?为什么在
stringWithFormat
中,格式说明符不受
%@
的尊重,但它们与
NSLog
一起使用


作为旁注,Swift
字符串init(格式:)
初始值设定项与
%@
和宽度说明符有相同的问题。

谜团在于为什么
%15@
会起作用。不应该

格式说明符来自
sprintf
,它没有
%@
(它只是Objective-C的一个特殊扩展)。就
stringWithFormat
而言,
%15s
一直是这样说的;我可以举一些例子,例如


我猜它只能“工作”,因为它现在在引擎盖下使用
os\u log
;不幸的是,
os\u log
语法几乎完全没有文档记录。

“在大多数情况下,NSLog现在只是os\u log的一个垫片。”来源:我怀疑,如果您使用足够旧的Xcode版本尝试此操作,您会发现NSLog与
stringWithFormat
行为匹配。我理解
%15s
工作的原因。问题是为什么
%15@
NSLog
中工作,而不是
nsstringwithformat:
“问题是为什么%15@在NSLog中工作”是的,我是说“我不知道,因为它不应该这样做。”:)我猜这是因为它现在在引擎盖下使用了
os\u log
;不幸的是,
os\u log
语法几乎完全没有文档记录。