NSHTTPURLResponse allHeaderFields区分大小写

Sas*_*ats 5 objective-c nsdictionary key-value-observing

为什么-[[NSHTTPURLResponse allHeaderFields] valueForKey:]不区分大小写,而valueForKey:对于手动创建NSDictionary则不是?

两者似乎都是NSCFDictionary;

使用变量,第一个Content-Type,即content-type,ConTEnt-TYPe返回相同的值

手动创建任何拼写的NSDictionary *a = @{ @"content-type" : @"pillows" }返回nil,然后小写"content-type"

编辑结果当下降到核心基础级别时,可以轻松实现此行为:https://gist.github.com/steipete/7739473

Pet*_*nev 4

它们并不都是 NSCFDictionary

- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse *)response
{
    NSDictionary *dictionary1 = [(NSHTTPURLResponse*)response allHeaderFields];
    NSDictionary *dictionary2 = [NSDictionary dictionaryWithObjects:[dictionary1 allValues] forKeys:[dictionary1 allKeys]];
}
Run Code Online (Sandbox Code Playgroud)

在LLDB中:

(lldb) po [dictionary2 class]
__NSDictionaryI
(lldb) po [dictionary1 class]
__NSCFDictionary
Run Code Online (Sandbox Code Playgroud)

似乎 __NSCFDictionary 键实际上不区分大小写 0_0。
__NSCFDictionary 的类继承看起来如此:__NSCFDictinary <-- NSMutableDictionary <-- NSDictionary。
对于 __NSDictionaryI: __NSDictionaryI <-- NSDictionary
检查调试输出:

(lldb) po [dictionary1 superclass]
NSMutableDictionary
(lldb) po [[dictionary1 superclass] superclass]
NSDictionary
(lldb) po [dictionary2 superclass]
NSDictionary
Run Code Online (Sandbox Code Playgroud)

我还创建了

NSMutableDictionary *dictionary3 = [dictionary2 mutableCopy];
Run Code Online (Sandbox Code Playgroud)

并尝试过

(lldb) po [dictionary3 class]
__NSDictionaryM
(lldb) po [[dictionary3 class] superclass]
NSMutableDictionary
(lldb) po [[[dictionary3 class] superclass] superclass]
NSDictionary
(lldb) po dictionary3[@"date"]
 nil
(lldb) po dictionary3[@"Date"]
Sun, 01 Dec 2013 13:35:22 GMT
Run Code Online (Sandbox Code Playgroud)

所以看起来只有 NSMutableDictionary 的 __NSCFDictionary 子类具有不区分大小写的键。
而且..我认为这是通过-objectForKey: -setObject:forKey:实施实现的。不是通过自定义 NSString 的。
此外,这__NSCFDictionary是 NSMutableDictionary 的不可变子类。它重写setObject:forKey:以引发异常。
所以简短的答案是:
它是由苹果公司通过一些私人基金会字典类完成的。