所以我使用 TLMutableDictionaryNoncopiedKeys 类别来找到这里的 NSMutableDictionary ,它允许使用不可复制的对象作为字典的键(我需要对象到对象的映射)。一切都很好,直到我被告知应用程序在 iOS 6 中崩溃。所以我下载了带有 iOS 6 的 XCode 4.5 进行测试,似乎 CFDictionary 函数存在一些问题。如果我将 UIView 作为键(在我的类别方法中)传递,它会崩溃:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIView copyWithZone:]: unrecognized selector sent to instance 0x719ff70'
来自 AppCode 调试器的更多详细信息:
objc_exception_throw
-[NSObject(NSObject) doesNotRecognizeSelector:]
__forwarding__
_CF_forwarding_prep_0
-[__NSDictionaryM setObject:forKey:]
-[NSMutableDictionary __addObject:forKey:]
CFDictionaryAddValue
-[NSMutableDictionary(TLMutableDictionaryNoncopiedKeys) setObject:forUncopiedKey:]
我做了一个测试项目。它适用于 iOS 5.1 模拟器,但在 6 时崩溃。
任何人都可以对此有所了解吗?
完整的项目在这里。以下是一些清单:
类别:
#import <Foundation/Foundation.h>
@interface NSMutableDictionary (TLMutableDictionaryNoncopiedKeys)
- (void)setObject:(id)anObject forUncopiedKey:(id)aKey;
@end
----------------------------------------------------------------------
#import "NSMutableDictionary+TLMutableDictionaryNoncopiedKeys.h"
@implementation NSMutableDictionary (TLMutableDictionaryNoncopiedKeys)
- (void)setObject:(id)anObject forUncopiedKey:(id)aKey
{
CFMutableDictionaryRef selfCF = (CFMutableDictionaryRef)self;
Boolean keyAlreadySet = CFDictionaryContainsKey(selfCF, aKey);
if (keyAlreadySet) {
CFDictionaryReplaceValue(selfCF, aKey, anObject);
}
else {
CFDictionaryAddValue(selfCF, aKey, anObject);
}
}
@end
用法:
#import "NSMutableDictionary+TLMutableDictionaryNoncopiedKeys.h"
...
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
UIView *key = [[UIView alloc] init];
[dict setObject:key forUncopiedKey:key];