swift Objective-C Dictionary 的一个有意思的区别
上代码
swift
func setKeyValue(map: inout [AnyHashable : String], key: AnyHashable, value: String) {
print("swift: set key:\(key) value:\(value)")
map[key] = value
print("swift: \(map)")
}
func testDictioary() {
var map: [AnyHashable : String] = [:]
setKeyValue(map: &map, key: true, value: "true")
setKeyValue(map: &map, key: false, value: "false")
setKeyValue(map: &map, key: UInt32(0), value: "UInt32(0)")
setKeyValue(map: &map, key: UInt32(1), value: "UInt32(1)")
setKeyValue(map: &map, key: UInt64(0), value: "UInt64(0)")
setKeyValue(map: &map, key: UInt64(1), value: "UInt64(1)")
setKeyValue(map: &map, key: Int32(0), value: "Int32(0)")
setKeyValue(map: &map, key: Int32(1), value: "Int32(1)")
setKeyValue(map: &map, key: Int64(0), value: "Int64(0)")
setKeyValue(map: &map, key: Int64(1), value: "Int64(1)")
setKeyValue(map: &map, key: Float32(0), value: "Float32(0)")
setKeyValue(map: &map, key: Float32(1), value: "Float32(1)")
setKeyValue(map: &map, key: Float64(0), value: "Float64(0)")
setKeyValue(map: &map, key: Float64(1), value: "Float64(1)")
print("swift: result \(map)")
let objcDictionary = map as NSDictionary
print("swift: result as NSDictionary \(objcDictionary)")
OC.printDictioary(map)
}
objc
// .h
@interface OC : NSObject
+ (void)testDictioary;
+ (void)printDictioary:(NSDictionary *)dict;
@end
//.m
static void setKeyVulue(NSMutableDictionary * dict, id key, id value) {
NSLog(@"oc: set key:%@ %@ value:%@", [key class], key, value);
dict[key] = value;
NSLog(@"oc:%@", dict);
}
@implementation OC
+ (void)testDictioary {
NSMutableDictionary * dict = [NSMutableDictionary dictionary];
setKeyVulue(dict, @(true), @"@true");
setKeyVulue(dict, @(false), @"@false");
setKeyVulue(dict, [NSNumber numberWithBool:true], @"true");
setKeyVulue(dict, [NSNumber numberWithBool:false], @"false");
setKeyVulue(dict, [NSNumber numberWithUnsignedInt:0], @"UInt32(0)");
setKeyVulue(dict, [NSNumber numberWithUnsignedInt:1], @"UInt32(1)");
setKeyVulue(dict, [NSNumber numberWithUnsignedLong:0], @"UInt64(0)");
setKeyVulue(dict, [NSNumber numberWithUnsignedLong:1], @"UInt64(1)");
setKeyVulue(dict, [NSNumber numberWithInt:0], @"Int32(0)");
setKeyVulue(dict, [NSNumber numberWithInt:1], @"Int32(1)");
setKeyVulue(dict, [NSNumber numberWithLong:0], @"Int64(0)");
setKeyVulue(dict, [NSNumber numberWithLong:1], @"Int64(1)");
setKeyVulue(dict, [NSNumber numberWithFloat:0], @"Float32(0)");
setKeyVulue(dict, [NSNumber numberWithFloat:1], @"Float32(1)");
setKeyVulue(dict, [NSNumber numberWithDouble:0], @"Float64(0)");
setKeyVulue(dict, [NSNumber numberWithDouble:1], @"Float64(1)");
NSLog(@"oc: result: %@", dict);
}
+ (void)printDictioary:(NSDictionary *)dict {
[dict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
NSLog(@"%@ %@: %@", [(NSObject *)key class], key, obj);
}];
}
@end
log
swift
swift: set key:true value:true
swift: [AnyHashable(true): "true"]
swift: set key:false value:false
swift: [AnyHashable(true): "true", AnyHashable(false): "false"]
swift: set key:0 value:UInt32(0)
swift: [AnyHashable(0): "UInt32(0)", AnyHashable(true): "true", AnyHashable(false): "false"]
swift: set key:1 value:UInt32(1)
swift: [AnyHashable(false): "false", AnyHashable(1): "UInt32(1)", AnyHashable(0): "UInt32(0)", AnyHashable(true): "true"]
swift: set key:0 value:UInt64(0)
swift: [AnyHashable(false): "false", AnyHashable(1): "UInt32(1)", AnyHashable(0): "UInt64(0)", AnyHashable(true): "true"]
swift: set key:1 value:UInt64(1)
swift: [AnyHashable(false): "false", AnyHashable(1): "UInt64(1)", AnyHashable(0): "UInt64(0)", AnyHashable(true): "true"]
swift: set key:0 value:Int32(0)
swift: [AnyHashable(false): "false", AnyHashable(1): "UInt64(1)", AnyHashable(0): "Int32(0)", AnyHashable(true): "true"]
swift: set key:1 value:Int32(1)
swift: [AnyHashable(false): "false", AnyHashable(1): "Int32(1)", AnyHashable(0): "Int32(0)", AnyHashable(true): "true"]
swift: set key:0 value:Int64(0)
swift: [AnyHashable(false): "false", AnyHashable(1): "Int32(1)", AnyHashable(0): "Int64(0)", AnyHashable(true): "true"]
swift: set key:1 value:Int64(1)
swift: [AnyHashable(false): "false", AnyHashable(1): "Int64(1)", AnyHashable(0): "Int64(0)", AnyHashable(true): "true"]
swift: set key:0.0 value:Float32(0)
swift: [AnyHashable(false): "false", AnyHashable(1): "Int64(1)", AnyHashable(0): "Float32(0)", AnyHashable(true): "true"]
swift: set key:1.0 value:Float32(1)
swift: [AnyHashable(false): "false", AnyHashable(1): "Float32(1)", AnyHashable(0): "Float32(0)", AnyHashable(true): "true"]
swift: set key:0.0 value:Float64(0)
swift: [AnyHashable(false): "false", AnyHashable(1): "Float32(1)", AnyHashable(0): "Float64(0)", AnyHashable(true): "true"]
swift: set key:1.0 value:Float64(1)
swift: [AnyHashable(false): "false", AnyHashable(1): "Float64(1)", AnyHashable(0): "Float64(0)", AnyHashable(true): "true"]
swift: result [AnyHashable(false): "false", AnyHashable(1): "Float64(1)", AnyHashable(0): "Float64(0)", AnyHashable(true): "true"]
swift: result as NSDictionary {
0 = false;
1 = "Float64(1)";
0 = "Float64(0)";
1 = true;
}
2021-06-25 13:57:28.915145+0800 TS[40462:1220674] __NSCFBoolean 1: true
2021-06-25 13:57:28.915668+0800 TS[40462:1220674] __NSCFNumber 0: Float64(0)
2021-06-25 13:57:28.915758+0800 TS[40462:1220674] __NSCFBoolean 0: false
2021-06-25 13:57:28.915841+0800 TS[40462:1220674] __NSCFNumber 1: Float64(1)
objc
2021-06-25 14:05:31.264627+0800 TS[40537:1225701] oc: set key:__NSCFNumber 1 value:@true
2021-06-25 14:05:31.264755+0800 TS[40537:1225701] oc:{
1 = "@true";
}
2021-06-25 14:05:31.264794+0800 TS[40537:1225701] oc: set key:__NSCFNumber 0 value:@false
2021-06-25 14:05:31.264855+0800 TS[40537:1225701] oc:{
0 = "@false";
1 = "@true";
}
2021-06-25 14:05:31.264887+0800 TS[40537:1225701] oc: set key:__NSCFBoolean 1 value:true
2021-06-25 14:05:31.264939+0800 TS[40537:1225701] oc:{
0 = "@false";
1 = true;
}
2021-06-25 14:05:31.264968+0800 TS[40537:1225701] oc: set key:__NSCFBoolean 0 value:false
2021-06-25 14:05:31.265003+0800 TS[40537:1225701] oc:{
0 = false;
1 = true;
}
2021-06-25 14:05:31.265034+0800 TS[40537:1225701] oc: set key:__NSCFNumber 0 value:UInt32(0)
2021-06-25 14:05:31.283843+0800 TS[40537:1225701] oc:{
0 = "UInt32(0)";
1 = true;
}
2021-06-25 14:05:31.283919+0800 TS[40537:1225701] oc: set key:__NSCFNumber 1 value:UInt32(1)
2021-06-25 14:05:31.284109+0800 TS[40537:1225701] oc:{
0 = "UInt32(0)";
1 = "UInt32(1)";
}
2021-06-25 14:05:31.284183+0800 TS[40537:1225701] oc: set key:__NSCFNumber 0 value:UInt64(0)
2021-06-25 14:05:31.284317+0800 TS[40537:1225701] oc:{
0 = "UInt64(0)";
1 = "UInt32(1)";
}
2021-06-25 14:05:31.284393+0800 TS[40537:1225701] oc: set key:__NSCFNumber 1 value:UInt64(1)
2021-06-25 14:05:31.284498+0800 TS[40537:1225701] oc:{
0 = "UInt64(0)";
1 = "UInt64(1)";
}
2021-06-25 14:05:31.284581+0800 TS[40537:1225701] oc: set key:__NSCFNumber 0 value:Int32(0)
2021-06-25 14:05:31.284658+0800 TS[40537:1225701] oc:{
0 = "Int32(0)";
1 = "UInt64(1)";
}
2021-06-25 14:05:31.284719+0800 TS[40537:1225701] oc: set key:__NSCFNumber 1 value:Int32(1)
2021-06-25 14:05:31.284825+0800 TS[40537:1225701] oc:{
0 = "Int32(0)";
1 = "Int32(1)";
}
2021-06-25 14:05:31.284888+0800 TS[40537:1225701] oc: set key:__NSCFNumber 0 value:Int64(0)
2021-06-25 14:05:31.284999+0800 TS[40537:1225701] oc:{
0 = "Int64(0)";
1 = "Int32(1)";
}
2021-06-25 14:05:31.285050+0800 TS[40537:1225701] oc: set key:__NSCFNumber 1 value:Int64(1)
2021-06-25 14:05:31.285139+0800 TS[40537:1225701] oc:{
0 = "Int64(0)";
1 = "Int64(1)";
}
2021-06-25 14:05:31.285204+0800 TS[40537:1225701] oc: set key:__NSCFNumber 0 value:Float32(0)
2021-06-25 14:05:31.285274+0800 TS[40537:1225701] oc:{
0 = "Float32(0)";
1 = "Int64(1)";
}
2021-06-25 14:05:31.285323+0800 TS[40537:1225701] oc: set key:__NSCFNumber 1 value:Float32(1)
2021-06-25 14:05:31.285376+0800 TS[40537:1225701] oc:{
0 = "Float32(0)";
1 = "Float32(1)";
}
2021-06-25 14:05:31.285429+0800 TS[40537:1225701] oc: set key:__NSCFNumber 0 value:Float64(0)
2021-06-25 14:05:31.285506+0800 TS[40537:1225701] oc:{
0 = "Float64(0)";
1 = "Float32(1)";
}
2021-06-25 14:05:31.285583+0800 TS[40537:1225701] oc: set key:__NSCFNumber 1 value:Float64(1)
2021-06-25 14:05:31.285674+0800 TS[40537:1225701] oc:{
0 = "Float64(0)";
1 = "Float64(1)";
}
2021-06-25 14:05:31.285795+0800 TS[40537:1225701] oc: result: {
0 = "Float64(0)";
1 = "Float64(1)";
}
2021-06-25 14:05:31.285896+0800 TS[40537:1225701] __NSCFNumber 0: Float64(0)
2021-06-25 14:05:31.285999+0800 TS[40537:1225701] __NSCFNumber 1: Float64(1)
结论
- @(true) @(false) 类型是 __NSCFNumber
- [NSNumber numberWithBool:v] 类型是 __NSCFBoolean
- 有意思的是 相同的操作 swift和oc得到了2种不同的结果
// swift
__NSCFBoolean 1: true
__NSCFNumber 0: Float64(0)
__NSCFBoolean 0: false
__NSCFNumber 1: Float64(1)
//oc
__NSCFNumber 0: Float64(0)
__NSCFNumber 1: Float64(1)
- oc 中 true和1 相等, false和0相等
- swift 中 true和1不相等, false和0不相等的
- swift、oc uint32、int32、uint64、int64、float、 double 使用相同的hash、equal规则
延伸思考
- 设计一种hash算法 实现 uint32、int32、uint64、int64、float、 double 相同值时hashCode一致