swift Objective-C Dictionary/Number 的一个有意思的区别

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一致

你可能感兴趣的:(swift Objective-C Dictionary/Number 的一个有意思的区别)