[英]iOS Incompatible Pointer Types (NSMutableDictionary from NSDictionary)
[英]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
因此,如果我有一个NSDictionary
或NSMutableDictionary
的对象,没有try块(我宁愿避免),我怎么能区分呢?
老实说,如果没有@try
块,你就无法轻易区分@try
。 标准做法如下:
copy
字典。 如果它真的不可变,那么框架会将其优化为retain
。 如果它确实是可变的,那么你可能还是想要一个副本。 NSAssert([bar isMemberOfClass: [NSMutableDictionary class]], @"");
实际上它很简单,你需要做的就是测试类的成员,如下所示:
if ([bar isMemberOfClass:[NSMutableDictionary class]]){
[bar setValue:value forKey: key];
}
我最终使用@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是否可变可以被视为代码气味的示例,表明存在应该解决的更深层次的问题。 换句话说,您应该始终知道给定的字典实例是NSDictionary还是NSMutableDictionary。 在这一点上代码应该清楚。
如果你真的不在乎它是否可变,但想要改变它,你可以试试这个:
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.