そのため、ここにあるNSMutableDictionaryのTLMutableDictionaryNoncopiedKeysカテゴリを使用していました。これにより、コピーできないオブジェクトを辞書のキーとして使用できます(オブジェクト間のマッピングが必要です)。iOS 6でアプリがクラッシュすると言われるまでは、すべて問題ありませんでした。そこで、iOS6でXCode4.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 Simulatorではうまく機能しますが、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];