setValue和setObject objectForKey和setobject的区别【字典注意事项】

1、总结

  • setValue和valueForKeyKVC的主要方法,setObject和objectForKeyNSMutableDictionary的特性;
  • setValue和valueForKey的KVC方式,相比NSMutableDictionary的特性的好处就是setValue时,value可以为nil。不好的是key只能字符串类型,否则valueForKey取值时会崩溃;
  • objectForKey和setobject的NSMutableDictionary的特性,相比KVC的好处是Key可以为任意类型,不好的就是value不能nil,否则setObject的时候会崩溃
  • 共同点是,key值都不能为nil
  • 在实际使用的时候,想要保证安全性,达到以下条件才可取值或set
    • set设置值时
      • setobject:key和value都不能为nil且是可变字典【key!= nil && value != nil && [dic isKindOfClass:[NSMutableDictionary Class]]】
      • setValue: key为字符串类型且为可变字典【[key isKindOfClass:[NSString string]] && [dic isKindOfClass:[NSMutableDictionary Class]]】
    • ForKey取值时
      • objectForKey:key不能为nil【key!= nil】
      • valueForKey: key为字符串类型【[key isKindOfClass:[NSString string]]】

2、具体分析

2.1、NSMutableDictionary的特性 【setobject和objectForKey】

  • Value 可以为除了nil外的任何对象

  • Key 可以为除了nil外的任何对象【即key不可为nil,为nil直接崩溃,但是可以为其他任意类型的对象,如:空字符串@"",空对象[NSNull null],其他类型的对象(如数组)】

    • setobject中的key除了不能为nil,其他都可以

    • objectForKey中的Key除了不能为nil,其他都可以

  • 示范

// Value 示范

    NSArray *arry = [NSArray arrayWithObject:[NSNumber numberWithInteger:888888]];
    NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
    
    [dic setObject:@"2" forKey:@"keyStr1"];
    [dic setObject:@"" forKey:@"keyStr2"];
    [dic setObject:[NSNull null] forKey:@"keyStr3"];
    [dic setObject:arry forKey:@"keyStr5"];
//    [dic setObject:nil forKey:@"keyStr4"]; // [崩溃]


// 结果 Value不能为nil

(lldb) po dic
{
    keyStr1 = 2;
    keyStr2 = "";
    keyStr3 = "";
    keyStr5 =     (
        888888
    );
}

// Key 示范

   NSArray *arry = [NSArray arrayWithObject:[NSNumber numberWithInteger:888888]];
   NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
   
   //1、key 为空对象[NSNull null]
   [dic setObject:@"1" forKey:[NSNull null]]; //【不崩溃+有警告】
   [dic objectForKey:[NSNull null]]; //字典属性取值,能取出值 【不崩溃】
//    [dic valueForKey:[NSNull null]];//KVC取值 【崩溃】
   
   //2、key 为nil
//        [dic setValue:@"3" forKey:nil]; //崩溃
   
    //3、key 为非字符串对象 arry
   [dic setObject:@"4" forKey:arry];//【不崩溃+有警告】
   [dic objectForKey:arry]; //字典属性取值,能取出值 【不崩溃】
//    [dic valueForKey:arry];//KVC取值 【崩溃】
   
   
   //4、key 为空字符串@“”
   [dic setObject:@"2" forKey:@""]; //【不崩溃】
   [dic objectForKey:@""]; //字典属性取值 能取出值 【不崩溃】
   [dic valueForKey:@""];//KVC取值 能取出值 【不崩溃】
   
   //5、key 为字符串
   [dic setObject:@"5" forKey:@"number"]; //【不崩溃】
   [dic objectForKey:@"number"]; //字典属性取值,能取出值 【不崩溃】
   [dic valueForKey:@"number"];//KVC取值 能取出值 【不崩溃】
   
   
//结果 
(lldb) po dic
{
   "" = 1;
}

(lldb) po [dic objectForKey:[NSNull null]]
1

(lldb) po [dic valueForKey:[NSNull null]]
error: cannot initialize a parameter of type 'NSString * _Nonnull' with an rvalue of type 'NSNull * _Nonnull'
passing argument to parameter 'key' here
(lldb) po [dic setValue:@"3" forKey:nil]
error: Execution was interrupted, reason: internal ObjC exception breakpoint(-4)..
The process has been returned to the state before expression evaluation.
(lldb) po dic
{
   "" = 1;
       (
       888888
   ) = 4;
}

(lldb) po [dic objectForKey:arry]
4

(lldb) po [dic valueForKey:arry]
error: cannot initialize a parameter of type 'NSString * _Nonnull' with an lvalue of type 'NSArray *'
passing argument to parameter 'key' here
(lldb) po [dic setObject:@"2" forKey:@""]
error: cannot initialize a parameter of type 'id _Nonnull' with an rvalue of type 'NSString *'
passing argument to parameter 'aKey' here
(lldb) po [dic objectForKey:@""]
nil
(lldb) po [dic valueForKey:@""]
nil
(lldb) po dic
{
   "" = 2;
       (
       888888
   ) = 4;
   number = 5;
   "" = 1;
}

(lldb) po [dic objectForKey:@"number"]
5

(lldb) po [dic valueForKey:@"number"]
5

(lldb) 

2.2、 KVC 【setValue和valueForKey】

  • Value 可以为nil也可以为空对象[NSNull null]以及全部对象

  • Key 只能为字符串包括空字符串,不能为其他对象

    • setValue中的key除了不能为nil,其他都可以【如:[NSNull null],arry,@"",@"keystr"】

    • valueForKey中的key只能为字符串包括空字符串@"",不能为其他的【即nil或其他类型】,其他一律崩溃

    • 所以综上所述如果用KVC的方法setValue和valueForKey来使用dic,通常说Key只能为字符串包括空字符串。所以在实际应用中使用KVC来使用字典只要判断key是否为string对象,就可以做到相应的读写安全【可变数组set之前还需要判断是否为可变字典】

  • 示范

// Value 示范

    NSArray *arry = [NSArray arrayWithObject:[NSNumber numberWithInteger:888888]];
    NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
    
    [dic setValue:@"2" forKey:@"keyStr1"]; 
    [dic setValue:@"" forKey:@"keyStr2"]; 
    [dic setValue:[NSNull null] forKey:@"keyStr3"]; 
    [dic setValue:nil forKey:@"keyStr4"]; 
    [dic setValue:arry forKey:@"keyStr5"]; 


// 结果 都set成功

(lldb) po dic
{
    keyStr1 = 2;
    keyStr2 = "";
    keyStr3 = "";
    keyStr5 =     (
        888888
    );
}

// Key 示范

    NSArray *arry = [NSArray arrayWithObject:[NSNumber numberWithInteger:888888]];
    NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
    
    //1、key 为空对象[NSNull null]
    [dic setValue:@"1" forKey:[NSNull null]]; //【不崩溃+有警告】
    [dic objectForKey:[NSNull null]]; //字典属性取值,能取出值 【不崩溃】
//    [dic valueForKey:[NSNull null]];//KVC取值 【崩溃】
    
    //2、key 为nil
//        [dic setValue:@"3" forKey:nil]; //崩溃
    
     //3、key 为非字符串对象 arry
    [dic setValue:@"4" forKey:arry];//【不崩溃+有警告】
    [dic objectForKey:arry]; //字典属性取值,能取出值 【不崩溃】
//    [dic valueForKey:arry];//KVC取值 【崩溃】
    
    
    //4、key 为空字符串@“”
    [dic setValue:@"2" forKey:@""]; //【不崩溃】
    [dic objectForKey:@""]; //字典属性取值 能取出值 【不崩溃】
    [dic valueForKey:@""];//KVC取值 能取出值 【不崩溃】
    
    //5、key 为字符串
    [dic setValue:@"5" forKey:@"number"]; //【不崩溃】
    [dic objectForKey:@"number"]; //字典属性取值,能取出值 【不崩溃】
    [dic valueForKey:@"number"];//KVC取值 能取出值 【不崩溃】
// 结果 都set成功

(lldb) po dic
{
    "" = 1;
}

(lldb) po [dic objectForKey:[NSNull null]]
1

(lldb) po [dic valueForKey:[NSNull null]] // 【崩溃】
error: cannot initialize a parameter of type 'NSString * _Nonnull' with an rvalue of type 'NSNull * _Nonnull'
passing argument to parameter 'key' here
(lldb) po [dic setValue:@"3" forKey:nil] 【崩溃】
error: Execution was interrupted, reason: internal ObjC exception breakpoint(-4)..
The process has been returned to the state before expression evaluation.
(lldb) po dic
{
        (
        888888
    ) = 4;
    "" = 1;
}

(lldb) po [dic objectForKey:arry]
4

(lldb) po [dic valueForKey:arry] 【崩溃】
error: cannot initialize a parameter of type 'NSString * _Nonnull' with an lvalue of type 'NSArray *'
passing argument to parameter 'key' here
(lldb) po dic
{
    "" = 2;
        (
        888888
    ) = 4;
    "" = 1;
}

(lldb) po [dic objectForKey:@""]
2

(lldb) po [dic valueForKey:@""]
2

(lldb) po dic
{
    "" = 2;
        (
        888888
    ) = 4;
    number = 5;
    "" = 1;
}

(lldb) po [dic objectForKey:@"number"]
5

(lldb) po [dic valueForKey:@"number"]
5

(lldb) 

你可能感兴趣的:(setValue和setObject objectForKey和setobject的区别【字典注意事项】)