iOS开发中setObject:ForKey和setValue:ForKey的用法和区别

      开发中会遇到这样的两个API,有时候后台数据为空的时候,没有做兼容,那么直接炸了,稍微留一下具体的意思


1.- (void)setObject:(ObjectType)anObject forKey:(KeyType )aKey; (字典专属方法)

anObject
// key对应的valye 强引用对象 retaincount +1
The value for aKey. A strong reference to the object is maintained by the dictionary.


Important
// 如果对象为nil,直接炸,要存空对象的话只能存[NSNull null],这里申明是ObjectType对象
Raises an invalidArgumentException if anObject is nil. 
If you need to represent a nil value in the dictionary, use NSNull.


aKey
// 遵守NSCopying协议的 如果key存在就替换原有的值
The key for value. The key is copied (using copy(with:); keys must conform to the NSCopying protocol). 
If aKey already exists in the dictionary, anObject takes its place.


Important
// key为nil的时候后也炸
Raises an invalidArgumentException if aKey is nil.



例子:

    NSMutableDictionary *dictM = [[NSMutableDictionary alloc] init];
    [dictM setObject:@"object" forKey:@"obj"]; // *** setObjectForKey: key cannot be nil'
    NSLog(@"%@",dictM);
    NSLog(@"打印下1:%@",dictM[@"obj"]);
    NSLog(@"打印下2:%@",dictM[@"1"]);
    [dictM setObject:[NSNull null] forKey:@"dd"];
    NSLog(@"打印3:%@",dictM);
    NSLog(@"打印4:%@",dictM[@"dd"]);
    2016-11-08 18:23:53.659 sb[6197:457577] {
        obj = object;
    }
    2016-11-08 18:23:53.660 sb[6197:457577] 打印下1:object
    2016-11-08 18:23:53.660 sb[6197:457577] 打印下2:(null)
    2016-11-08 18:23:53.660 sb[6197:457577] 打印3:{
        dd = "";
        obj = object;
    }
    2016-11-08 18:23:53.661 sb[6197:457577] 打印4:

正常情况下就是这样的,value 和 key都不为nil
当两者有一个为nil的时候就直接崩溃
而且你要存空值只能存ObjectType类型的,也就是[NSNull null]空对象
打印的时候如果key不存在,取出来的值是(null)
如果key存在,存的是空对象,打印就是



2.- (void)setValue:(nullable ObjectType)value forKey:(NSString *)key;(NSObject KVC的核心方法)

// 其实调用的就是上面介绍的setObject:forKey的方法 如果value是nil。那么就是调用remveObjectForKey了
/* Send -setObject:forKey: to the receiver, unless the value is nil, 
in which case send -removeObjectForKey:.
*/

注意看,其实API里面都写的很详细了

nullable ObjectType value可以传空值

(NSString *)key key必须是字符串类型


NSMutableDictionary *dictM = [[NSMutableDictionary alloc] init];
    [dictM setValue:@"value" forKey:@"val"]; // '*** setValueForKey: key cannot be nil'
    [dictM setValue:@"value1111" forKey:@"val1"];
    NSLog(@"%@",dictM);
    [dictM setValue:nil forKey:@"val"];
    NSLog(@"打印下1:%@",dictM);
    NSLog(@"打印下2:%@",dictM[@"1"]);
    2016-11-08 18:35:32.070 sb[6248:470292] {
        val = value;
        val1 = value1111;
    }
    2016-11-08 18:35:32.070 sb[6248:470292] 打印下1:{
        val1 = value1111;
    }
    2016-11-08 18:35:32.071 sb[6248:470292] 打印下2:(null)


这里value可以为nil,但是key还是不能为nil

当value为nil的时候就是remveObject:forKey

打印的时候如果key不存在,取出来的值是(null)



简单介绍下两者的区别
1.首先两者的key都不能为nil,setVlue:forKey的key只能是字符串类型 setObject:forKey的key可以使任意对象


2.setValue:forKey中的value可以为nil,为nil的时候调用removeObject:forKey,setObject:forKey中value不可以为nil


3.setObject是字典专属的方法,setVlue是任何对象的方法KVC的核心方法,例如
People *p1 = [[People alloc] init];
[p1 setValue:@"mkj" forKey:@"name"];
当对象有name属性的时候就是通过KVC来赋值


补充 10.31

objectForKey: 和 valueForKey: 在多数情况下都是一样的结果返回,但是如果 key 是以 @ 开头,valueForKey: 就成了一个大坑,建议在 NSDictionary 下只用 objectForKey: 来取值。

objectForKey 和 valueForKey 如果只是针对于NSDictionary来用,那么访问的key值无论是nil,还是不存在的key,返回的都是nil


但是如果你自定义的对象,你只能通过KVC valueForKey setValue: ForKey:来进行访问和赋值,那么如果这个时候,首先key肯定不能为nil

1.valueForKey 访问的时候 key不存在,就需要实现如下方法

- (id)valueForUndefinedKey:(NSString *)key{
    return @"";
}



2.setValue: ForKey: 赋值的时候key不存在

- (void)setValue:(id)value forUndefinedKey:(NSString *)key{
    
}

value不存在,就按上面所说,实际上调用的是 remveObject:forKey






你可能感兴趣的:(基础知识,setValueforKey,setObjectForKey,KVC,nullable)