1

アップデート:

辞書でnullオブジェクトをチェックするメソッドを追加しましたが、実際にそれらが見つかりました。

NSMutableDictionaryのヌル

誰かがこのようなものを見たことがありますか?これは、誤ったメモリ管理が原因ではありません。左側の辞書オブジェクトツリーは実際には正しいことに注意してください。

更新を終了

NSMutableDictionaryARCを有効にしてにいくつかのエントリを追加しています。追加の1つの後、追加されたオブジェクトは突然nullになります。これがコードです(私は怒っていないことを確認するためにそれを拡張しました):

NSMutableDictionary *base = [NSMutableDictionary dictionary];

id o = [GAConstant kTRUE];
id k = [GAClause parse:@"(x 1 1)"];
[base setObject:o forKey:k];
NSLog(@"### Added (%@ -> %@): %@", k, o, base);

o = [GAClause parse:@"(y X)"];
k = [GAClause parse:@"(x 2 X)"];
[base setObject:o forKey:k];
NSLog(@"### Added (%@ -> %@): %@", k, o, base);

o = [GAConstant kTRUE];
k = [GAClause parse:@"(y 3)"];
[base setObject:o forKey:k];
NSLog(@"### Added (%@ -> %@): %@", k, o, base);

o = [GAConstant kTRUE];
k = [GAClause parse:@"(y 6)"];
[base setObject:o forKey:k];
NSLog(@"### Added (%@ -> %@): %@", k, o, base);

出力は次のとおりです。

2013-03-25 16:10:33.546 Jungle[1978:11303] ### Added (<GAListClause: 0x75b0dc0> -> <GAConstant: 0x75b12b0>): {
    "<GAListClause: 0x75b1b00>" = "<GAConstant: 0x75b12b0>";
}
2013-03-25 16:10:33.548 Jungle[1978:11303] ### Added (<GAListClause: 0x75b2870> -> <GAListClause: 0x75b1aa0>): {
    "<GAListClause: 0x75b2270>" = "<GAListClause: 0x75b1aa0>";
    "<GAListClause: 0x75b1b00>" = "<GAConstant: 0x75b12b0>";
}
2013-03-25 16:10:33.549 Jungle[1978:11303] ### Added (<GAListClause: 0x75b2b90> -> <GAConstant: 0x75b12b0>): {
    "<GAListClause: 0x75b2d80>" = "<GAConstant: 0x75b12b0>";
    "<GAListClause: 0x75b2270>" = "<GAListClause: 0x75b1aa0>";
    "<GAListClause: 0x75b1b00>" = "<GAConstant: 0x75b12b0>";
}
2013-03-25 16:10:33.550 Jungle[1978:11303] ### Added (<GAListClause: 0x75b2f00> -> <GAConstant: 0x75b12b0>): {
    "<GAListClause: 0x75b2d80>" = "<GAConstant: 0x75b12b0>";
    "<GAListClause: 0x75b2270>" = "<GAListClause: 0x75b1aa0>";
    "<GAListClause: 0x75b1b00>" = "<GAConstant: 0x75b12b0>";
    "<GAListClause: 0x75b1d60>" = (null);
}

このメソッド[GAConstant kTRUE]は静的変数を初期化して返します。[GAClause parse:]毎回新しい解析済みオブジェクトを返します。

変数のアドレスが辞書の内容に対応していない理由は明らかです。k変数をコピーします。nullが値としてどのように侵入できるかはまだ明らかではありません。辞書内のnullの位置は、実行するたびに変化します。2つ取得することもあります。

メモリ管理で何かが起こっているように見えますが、何ですか?ここでARCが有効になります。

[GAConstant kTRUE]メソッドに関連するコードは次のとおりです。

+ (GAConstant *)kTRUE {
    static GAConstant *kTRUE = nil;
    static dispatch_once_t onceToken = 0;

    dispatch_once(&onceToken, ^{
        kTRUE = [[GAConstant alloc] initWithString:@"true"];
    });

    return kTRUE;
}

nullが辞書全体で変動している場合があります。

2013-03-25 17:09:16.426 Jungle[2294:11303] ### Added (<GAListClause: 0x7182ce0> -> <GAConstant: 0x7183430>): {
    "<GAListClause: 0x7183a30>" = "<GAConstant: 0x7183430>";
}
2013-03-25 17:09:16.428 Jungle[2294:11303] ### Added (<GAListClause: 0x75467b0> -> <GAListClause: 0x71839d0>): {
    "<GAListClause: 0x7546a30>" = (null);
    "<GAListClause: 0x7183a30>" = "<GAConstant: 0x7183430>";
}
2013-03-25 17:09:16.429 Jungle[2294:11303] ### Added (<GAListClause: 0x7546cd0> -> <GAConstant: 0x7183430>): {
    "<GAListClause: 0x7546ec0>" = "<GAConstant: 0x7183430>";
    "<GAListClause: 0x7546a30>" = "<GAListClause: 0x71839d0>";
    "<GAListClause: 0x7183a30>" = "<GAConstant: 0x7183430>";
}
2013-03-25 17:09:16.430 Jungle[2294:11303] ### Added (<GAListClause: 0x7547040> -> <GAConstant: 0x7183430>): {
    "<GAListClause: 0x75470f0>" = (null);
    "<GAListClause: 0x7546ec0>" = "<GAConstant: 0x7183430>";
    "<GAListClause: 0x7546a30>" = "<GAListClause: 0x71839d0>";
    "<GAListClause: 0x7183a30>" = "<GAConstant: 0x7183430>";
}

デバッガーでの表示は次のとおりです。

デバッガ

4

1 に答える 1

6

あなたの問題は非常に奇妙です。要約すると、デバッガーは辞書を正しいものとして表示しますが、をobjectForKey返しますnil

私はこの1時間これについて考えていましたが、これがどのように発生する可能性があるかを知っているのは1つの可能性、つまり間違っているhashisEqual:方法だけだと確信しています。

isEqual:特に、その方法は対称的ではないと思います。言い換えれば、

id k = [GAClause parse:@"(x 1 1)"];

それから

[k isEqual:k]

真実である必要はありません。

次に、辞書キーを取得してその値を見つけようとすると(これは同じです[NSDictionary description])、値は見つかりません。

ブレークポイント/を入れてNSLogisEqual値を比較したときに何が起こっているかを監視する必要があると思います。

また、辞書キーがコピーされるため、コピー中に等式の問題が発生する可能性があることにも注意してください。

于 2013-03-25T20:21:47.890 に答える