0

Xcode をアップグレードしたところ、次のような大量のアナライザー警告が表示されました。

25 行目に割り当てられ、「oneCopy」に格納されたオブジェクトの潜在的なリーク

誰かが私を正しい方向に向けることができますか?

@implementation NSDictionary(DeepMutableCopy)
-(NSMutableDictionary *)mutableDeepCopy
{
    NSMutableDictionary *ret = [[NSMutableDictionary alloc] initWithCapacity:[self count]];
    NSArray *keys = [self allKeys];
    for (id key in keys)
    {
        id oneValue = [self valueForKey:key];
        id oneCopy = nil;

        if ([oneValue respondsToSelector:@selector(mutableDeepCopy)])
            oneCopy = [oneValue mutableDeepCopy];
        else if ([oneValue respondsToSelector:@selector(mutableCopy)])
            oneCopy = [oneValue mutableCopy];
        if (oneCopy == nil)
            oneCopy = [oneValue copy];
        [ret setValue:oneCopy forKey:key];
    }
    return ret;
}
@end

行番号を示すスクリーンショット:
ここに画像の説明を入力

#import "NSDictionary-DeepMutableCopy.h"


@implementation NSDictionary(DeepMutableCopy)
-(NSMutableDictionary *)mutableDeepCopy
{
    //NSMutableDictionary *ret = [[NSMutableDictionary alloc] initWithCapacity:[self count]];
    NSMutableDictionary *ret = [NSMutableDictionary dictionaryWithCapacity:[self count]];
    NSArray *keys = [self allKeys];
    for (id key in keys)
    {
        id oneValue = [self valueForKey:key];
        id oneCopy = nil;

        if ([oneValue respondsToSelector:@selector(mutableDeepCopy)])
            oneCopy = [oneValue mutableDeepCopy];
        else if ([oneValue respondsToSelector:@selector(mutableCopy)])
            oneCopy = [oneValue mutableCopy];
        if (oneCopy == nil)
            oneCopy = [oneValue copy];
        [ret setValue:oneCopy forKey:key];
        [oneCopy release];
    }
    return ret;

}
@end
4

2 に答える 2

1

[[NSMutableDictionary alloc] initWithCapacity:[self count]]自動解放されたオブジェクトを返す which を使用する代わりに、最初に2番目の問題に対処[NSMutableDictionary dictionaryWithCapacity:[self count]]し、呼び出し元のコードでそれを保持する必要があります。

一方、保持されたオブジェクトを返し、エラーをスローしないようにする場合は、メソッドの名前を copy という単語で開始するように変更できます。これは、まさにこの場合にやりたいことだと思います。私の回答の残りの部分は、あなたがこの道をたどったことを前提としています。

私の最初の答えは次のとおりです。各反復の最後にoneCopyをリリースしていません。[oneCopy release];の直後に追加してみてください[ret setValue:oneCopy forKey:key];

ただし、Alexsander Akers が指摘しているように、コンパイラは -mutableDeepCopy の参照カウントが 0 であると見なします。したがって、上記のように名前を変更し、[oneCopy release]最初に提案したように含めると、両方の問題が処理されるはずです。そうでない場合は、彼が参照した質問の他の解決策を確認してください。

例:

@implementation NSDictionary(DeepMutableCopy)
-(NSMutableDictionary *)copyWithDeepCopiedValues
{
    NSMutableDictionary *ret = [[NSMutableDictionary alloc] initWithCapacity:[self count]];

    NSArray *keys = [self allKeys];
    for (id key in keys)
    {
        id oneValue = [self valueForKey:key];
        id oneCopy = nil;

        if ([oneValue respondsToSelector:@selector(mutableDeepCopy)])
            oneCopy = [oneValue copyWithDeepCopiedValues];
        else if ([oneValue respondsToSelector:@selector(mutableCopy)])
            oneCopy = [oneValue mutableCopy];
        if (oneCopy == nil)
            oneCopy = [oneValue copy];
        [ret setObject:oneCopy forKey:key];

        [oneCopy release];
    }

    return ret;
}
@end
于 2011-11-09T22:08:17.063 に答える
0

ここには 2 つの問題があります。まず、@ David Brainer-Banker が言うように、 [ret setValue:oneCopy forKey:key];`oneCopyを配置して、各反復の最後に解放する必要があります。[oneCopy release]; after you set

2 つ目の問題は、参照カウントのデクリメントが正しくないことです。これは、oneCopyオブジェクトが+1または0参照カウントを持つ可能性があるためです。-copyおよびによって返されるオブジェクトに-mutableCopy+1refcount がありますが、 によって返されるオブジェクトには、 、、または(その他) ファミリに含まれていないため-deepMutableCopy、 refcount があります。0newcopycreate

この質問は、この質問とまったく同じもので、すばらしい回答がいくつかあります。

于 2011-11-10T19:56:57.793 に答える