7

dispatch_once静的オブジェクトの作成に使用するクラス メソッドがあります。dispatch_once私が使用しているブロック内で、保持サイクルを回避するために[self class]弱い参照を使用する必要があるかどうか疑問に思っていましたか?self

+ (NSArray *)accountNames{
    static NSArray *names = nil;
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        names = [[[self class] accounts] allKeys];
        names = [names sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
    });
    return names;
}

弱い参照を使用するselfと、警告が表示されます。

+ (NSArray *)accountNames{
    static NSArray *names = nil;
    static dispatch_once_t predicate;
    __weak TUAccount *wself = self;
    dispatch_once(&predicate, ^{
        names = [[[wself class] accounts] allKeys];
        names = [names sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
    });
    return names;
}

'const Class' 型の式で 'TUAccount *__weak' を初期化する互換性のないポインター型

警告が表示されるので、この場合は弱参照を使用する必要はないと思いますが、self皆さんの考えを知りたいと思いました。

4

2 に答える 2

11

ここで保持サイクルについて心配する必要はありません。なぜなら、クラス オブジェクトを保持または解放することは無意味だからです。保持と解放はまったく効果がありません。

クラスオブジェクトを取得して のインスタンスselfキャストしようとしているため、弱参照を作成しようとする試みは間違っています。2つはまったく別のものです。TUAccount

また、次のように簡略化できます。

names = [[[self class] accounts] allKeys];

self は既にクラスであるため、 [self class] == self であるため、代わりに次のようにします。

names = [[self accounts] allKeys];
于 2012-06-05T06:29:47.893 に答える
0

もう一度 iOS SDK Docs を確認したところ、次のことがわかりました。

Objective-C オブジェクト

手動で参照カウントされる環境では、ブロック内で使用されるローカル変数は、ブロックがコピーされるときに保持されます。ブロック内でインスタンス変数を使用すると、オブジェクト自体が保持されます。特定のオブジェクト変数に対してこの動作をオーバーライドする場合は、__block ストレージ タイプ修飾子でマークできます。

ARC を使用している場合、ブロックがコピーされて後で解放されると、オブジェクト変数は自動的に保持および解放されます。

  • 注: ガベージ コレクション環境で、変数に __weak 修飾子と __block 修飾子の両方を適用すると、ブロックはその変数が存続することを保証しません。

メソッドの実装内でブロックを使用する場合、オブジェクト インスタンス変数のメモリ管理のルールはより微妙になります。

  • 参照によってインスタンス変数にアクセスする場合、self は保持されます。
  • インスタンス変数に値でアクセスすると、変数は保持されます。

次の例は、2 つの異なる状況を示しています。

dispatch_async(queue, ^{
    // instanceVariable is used by reference, self is retained
    doSomethingWithObject(instanceVariable);
});


id localVariable = instanceVariable;
dispatch_async(queue, ^{
    // localVariable is used by value, localVariable is retained (not self)
    doSomethingWithObject(localVariable);
});

self結論: in blockでの使用は問題ないと思います。保持され、実行後に解放されます。

さらに、ブロックをメモリに保存して直接使用していません。したがって、ヒープにコピーされ、実行され、ヒープからプッシュされます。保持サイクルは見られません。

私が正しいことを願っています!

于 2012-06-05T06:24:56.043 に答える