2

所以我使用 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];
4

0 回答 0