次のように定義されているように、辞書に「dateTime」を追加しようとしています。
Symptom Ranking: {
5111ef19253b4a9150000000 = 1;
5111f029253b4add4e000000 = 1;
5111f036253b4a123d000001 = 1;
5111f045253b4a404f000000 = 1;
}
NSLog(@"date selected: %@", [[self.datePicker date] description])
[self.results setObject:[[self.datePicker date] description] forKey:@"dateTime"];
アプリがクラッシュし、次のようになります。
Symptom Tracker[43134:c07] -[__NSDictionaryI setObject:forKey:]: unrecognized selector sent to instance 0x7603990
2013-02-06 08:15:58.741 Symptom Tracker[43134:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSDictionaryI setObject:forKey:]: unrecognized selector sent to instance 0x7603990'
*** First throw call stack:
(0x171b012 0x1428e7e 0x17a64bd 0x170abbc 0x170a94e 0x521e 0x143c705 0x373920 0x3738b8 0x434671 0x434bcf 0x433d38 0x3a333f 0x3a3552 0x3813aa 0x372cf8 0x2652df9 0x2652ad0 0x1690bf5 0x1690962 0x16c1bb6 0x16c0f44 0x16c0e1b 0x26517e3 0x2651668 0x37065c 0x25dd 0x2505)
辞書は不変です。これはNSDictionary
であり、NSMutableDictionary
ではありません。それを修正すれば、問題なく動作します。
私が誤ってcopy
プロパティを次のように宣言したときに、このエラーに遭遇しました:
@property (nonatomic,copy) NSMutableDictionary* downloadHandlers;
init
でこれを行ったとき:
self.downloadHandlers = [[NSMutableDictionary alloc] init];
私は実際に不変の辞書を手に入れました。可変オブジェクトでcopy
を呼び出すと、可変オブジェクトも得られると思っていましたが、明らかにそうではありませんでした。とにかく、copy
キーワード(最初からそこにあるつもりはなかった)を削除すると、問題が修正されました。
トップランクの回答で述べたように、NSMutableDictionary
ではなくNSDictionary
を使用する必要があります。また、リテラルを使用する場合は、mutableCopy
を次のように使用します。
NSMutableDictionary* dict = [@{@"key": @"value"} mutableCopy];
を使用してキーを再割り当てできるように
dict[@"key"] = @"new-value";
NSMutableDictionary
を使用する必要があります-スタックトレースは、不変の__NSDictionaryI
、(NSDictionary
)を使用していることを示しています
この問題は、受信したデータが不変であるため、ほとんどの場合、Webサービスの応答を処理しているときに発生します。不変のデータを変更しようとすると、アプリケーションは間違いなくクラッシュします。次のコードスニペットがお役に立てば幸いです。
NSMutableDictionary *headerData;
/*Every time you need to allocate memory to the corresponding MutableDictionary variable*/
headerData =[[NSMutableDictionary alloc ]initWithDictionary:response[@"Header"]];
私の場合、[AnyHashable:AnyObject]形式で値を返すSwiftコードがあり、それをNSMutableDictionaryに変換する必要がありました。
NSMutableDictionary *logDict = [[NSMutableDictionary alloc]initWithDictionary:[[AnalyticsManager shared]addCommonPropertiesWithProperties:logDict]];
[[AnalyticsManager shared] addCommonPropertiesWithProperties:logDict]として、この部分は[AnyHashable:AnyObject]形式で返されます。それで私の問題は解決しました。