繁体   English   中英

iOS - 区分NSDictionary和NSMutableDictionary?

[英]iOS — distinguish an NSDictionary from an NSMutableDictionary?

我有以下代码片段:

NSString* value = @"value";
NSString* key = @"key";
NSMutableDictionary* foo = [NSMutableDictionary dictionary];
NSDictionary* bar = [NSDictionary dictionary];
NSAssert([bar isKindOfClass: [NSMutableDictionary class]], @"");   // passes the assert as both are NSCFDictionary;
NSAssert([bar respondsToSelector: @selector(setValue:forKey:)], @"");   // passes the assert because it NSCFDictionary does respond to the selector
[foo setValue:value forKey:key];   // no problem, foo is mutable
[bar setValue:value forKey:key];   // crash

因此,如果我有一个NSDictionaryNSMutableDictionary的对象,没有try块(我宁愿避免),我怎么能区分呢?

老实说,如果没有@try块,你就无法轻易区分@try 标准做法如下:

  • 如果你想检查它是否可变,以避免有人通过你一个意想不到的可变对象,然后从你下面改变它, copy字典。 如果它真的不可变,那么框架会将其优化为retain 如果它确实可变的,那么你可能还是想要一个副本。
  • 如果需要可变字典,请声明方法参数以获取一个。 就那么简单。
  • 一般来说,相信人们不会试图改变对象,除非特别说明它们是可变的。
NSAssert([bar isMemberOfClass: [NSMutableDictionary class]], @"");

实际上它很简单,你需要做的就是测试类的成员,如下所示:

if ([bar isMemberOfClass:[NSMutableDictionary class]]){
    [bar setValue:value forKey: key];
}

iPhone SDK的区别在于isKindOfClass和isMemberOfClass

我最终使用@try catch但它只触发一次。 所以它就是这样的

NSMutableDictionary *valuesByIdMutable = (id)self.valuesById;

simplest_block block = ^{
    [valuesByIdMutable setObject:obj forKey:key];
};

@try {
    block();
} @catch (NSException *exception) {
    self.valuesById = valuesByIdMutable = [valuesByIdMutable mutableCopy];
    block();
}

如果您需要保证字典是可变的,您应该:

  • 如果你是初始化它,那么将它创建为可变的
  • 使用 - [NSDictionary mutableCopy]方法将其转换为可变实例,例如,如果您正在调用返回NSDictionary的API。 请注意,mutableCopy会增加保留计数; 如果使用手动引用计数,则需要释放此实例。

在尝试修改其密钥和/或值之前确定NSDictionary是否可变可以被视为代码气味的示例,表明存在应该解决的更深层次的问题。 换句话说,您应该始终知道给定的字典实例是NSDictionary还是NSM​​utableDictionary。 在这一点上代码应该清楚。

如果你真的不在乎它是否可变,但想要改变它,你可以试试这个:

NSString* value = @"value";
NSString* key = @"key";

NSDictionary* bar = [NSDictionary dictionary];
NSLog(@"bar desc: %@", [bar description]);
NSMutableDictionary* temp = [bar mutableCopy];
[temp setValue:value forKey:key];
bar = temp;
NSLog(@"bar desc: %@", [bar description]);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM