5

クラスで、新しいインスタンスが ( vis isEqual: andに対してhash) 既存のインスタンスと同等であることを検出し、一意のインスタンスのみを作成するようにしたいと考えています。これは私が仕事をしていると思うコードですが、私が見つけられないばかげたことをしているのではないかと心配しています...

次のような NSURLRequest サブクラスだとします。

// MyClass.h
@interface MyClass : NSMutableURLRequest
@end

// MyClass.m

@implementation MyClass

+ (NSMutableSet *)instances {

    static NSMutableSet *_instances;
    static dispatch_once_t once;

    dispatch_once(&once, ^{ _instances = [[NSMutableSet alloc] init];});
    return _instances;
}

- (id)initWithURL:(NSURL *)URL {

    self = [super initWithURL:URL];
    if (self) {
        if ([self.class.instances containsObject:self])
            self = [self.class.instances member:self];
        else
            [self.class.instances addObject:self];
    }
    return self;
}


// Caller.m
NSURL *urlA = [NSURL urlWithString:@"http://www.yahoo.com"];

MyClass *instance0 = [[MyClass alloc] initWithURL: urlA];
MyClass *instance1 = [[MyClass alloc] initWithURL: urlA];  // 2

BOOL works = instance0 == instance1;  // works => YES, but at what hidden cost?

質問:

  1. init での self への 2 番目の代入は奇妙に見えますが、正気ではありません。またはそれは?
  2. (instance1 の) 2 番目の割り当てが魔法のようにクリーンアップされると考えるのは、希望的なコーディングですか?
4

2 に答える 2

5
  1. 異常ではありませんが、手動の保持/解放モードでは、self事前に解放する必要があります。そうしないと、このメソッドが実行されるたびに初期化されていないオブジェクトがリークされます。ARC では、元のインスタンスが自動的に解放されます。

  2. #1を参照してください。

ところで、通常は 1 つの回答にとどまる読者のために、以下の bbum の回答には、スレッドセーフな実装の完全な実例が含まれています。これを行うクラスを作成する人には強くお勧めします。

于 2013-04-05T17:33:24.867 に答える