iOS – 区分NSDictionary和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
的对象,缺less一个尝试块(我宁愿避免),我怎么能区分?
NSAssert([bar isMemberOfClass: [NSMutableDictionary class]], @"");
老实说,没有一个@try
块就不能轻易分辨出区别。 标准做法如下:
- 如果你想检查它是否可变,以避免有人通过你一个意外的可变对象,然后从你下面突出它,
copy
字典。 如果它真的是不可变的,框架将优化成retain
。 如果它真的是可变的,那么你可能想要一个副本。 - 如果你需要一个可变的字典,声明你的方法参数需要一个。 就那么简单。
- 一般来说,相信人们不会试图改变对象,除非明确告诉他们是可变的。
实际上这很简单,你只需要testing一下类的成员就可以了:
if ([bar isMemberOfClass:[NSMutableDictionary class]]){ [bar setValue:value forKey: key]; }
iPhone SDK与isKindOfClass和isMemberOfClass之间的区别
如果你需要保证字典是可变的,你应该:
- 如果你是一个初始化它创build它为可变的
- 使用 – [NSDictionary mutableCopy]方法将其变成一个可变实例,例如,如果您正在调用返回NSDictionary的API。 请注意,mutableCopy递增保留计数; 如果使用手动引用计数,则需要释放此实例。
在尝试修改键和/或值之前确定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]);
我最终使用@try捕获,但它只发射一次。 所以它是这样的
NSMutableDictionary *valuesByIdMutable = (id)self.valuesById; simplest_block block = ^{ [valuesByIdMutable setObject:obj forKey:key]; }; @try { block(); } @catch (NSException *exception) { self.valuesById = valuesByIdMutable = [valuesByIdMutable mutableCopy]; block(); }
- iOS 7 TableView中ViewController和NavigationBar的模糊效果
- 我怎样才能使一个函数执行每秒迅速?
- CollectionView与背景图像
- 如何在自定义UIBarButtonItem上放置徽章
- 核心数据子上下文不是预取关系
- 从UIUserNotificationTypeNone传递到UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound
- Swift 100天:项目24 –如何仅将一个ViewController旋转为横向方向?
- 检测UIWebView链接,无需点击
- _BSMachError运行斯坦福的CS193p Smashtag应用程序