NSMapTable(これはiPhoneなどでは使用できません)を使用する代わりに、CoreFoundationの同等機能を使用することができます。それらは通常の保持されていないポインタを含むことができます。しかし、まだリストから取り除く必要がありますが、これはオブジェクトの-deallocメソッドで簡単に行うことができます。
1つの可能性は、CFSetを使用することです。これは、あなたのオブジェクトがすべて-isEqual:
と-hash
に正しく応答することを必要とするため、オブジェクトが既に正確に存在するかどうかをセットが判断できるようになります。例えば
(私はこれをコンパイルしていませんでしたが、それは、少なくとも90%の正解であるべきことに注意してください):
static id __uniqueObjects = nil; // GC uses NSHashTable, non-GC uses NSSet (inited using CFSet APIs)
@interface MyHost : NSObject
{
NSURL * _hostURL;
}
@property (nonatomic, readonly) NSURL * hostURL;
+ (MyHost *) uniqueHost: (MyHost *) aHost;
+ (void) removeUniqueHost: (MyHost *) aHost; // only used in non-GC environment
- (id) initWithURL: (NSURL *) hostURL;
@end
@implementation MyHost
- (id) initWithURL: (NSURL *) hostURL
{
self = [super init];
if (self == nil)
return (nil);
// use copy, because NSURL implements NSCopying protocol
_hostURL = [hostURL copy];
// if there's a version around already, release this instance
MyHost * result = [[self class] uniqueHost: self];
if (result != self)
{
// set _hostURL to nil so we don't inadvertently remove anything from uniqueing table in -dealloc
[_hostURL release];
_hostURL = nil;
[self release];
}
// return either self or a pre-existing unique instance
return (result);
}
- (void) dealloc
{
// non-GC objects need to explicitly remove themselves from the uniqueing table
[[self class] removeUniqueHost: self];
[_hostURL release];
[super dealloc];
}
// no need for -finalize -- under GC we use NSHashTable with weak references
- (NSUInteger) hash
{
return ([_hostURL hash]);
}
- (BOOL) isEqual: (MyHost *) other
{
if (other == self)
return (YES);
return ([_hostURL isEqual: other->_hostURL]);
}
+ (MyHost *) uniqueHost: (MyHost *) aHost
{
if (__uniqueObjects == nil)
{
// use low-level routine to check, because iPhone has no NSGarbageCollector class
// we use NSHashTable or NSMutableSet, because they both respond to the same messages (NSHashTable is modeled on NSMutableSet)
if (objc_collectingEnabled())
{
// hash table has zeroing weak memory, object equality (uses -isEqual:), and does NOT copy objects, just retains them
__uniqueObjects = [[NSHashTable hashTableWithWeakObjects] retain];
}
else
{
CFSetCallBacks cb = {
0, // version
NULL, // retain (non-retaining references)
NULL, // release (non-retaining references)
CFCopyDescription, // CF (plain C function) equivalent for -description
CFEqual, // CF (plain C function) equivalent for -isEqual:
CFHash // CF (plain C function) equivalent for -hash
}
__uniqueObjects = (NSMutableSet *) CFSetCreateMutable(kCFAllocatorDefault, 0, &cb);
}
}
MyHost * result = nil;
@synchronized(__uniqueObjects)
{
// treat both like an NSMutableSet & we're golden
// we use the -member: function to get an existing matching object from the collection
result = [[__uniqueObjects member: aHost] retain];
if (result == nil)
{
// store & return the passed-in host object
[__uniqueObjects addObject: aHost];
result = aHost;
}
}
return (result);
}
+ (void) removeUniqueHost: (MyHost *) aHost
{
if (__uniqueObjects == nil)
return; // shouldn't ever happen, but it's a good idea to check at least
@synchronized(__uniqueObjects)
{
[__uniqueObjects removeObject: aHost];
}
}
@end
がうまくいけば、私はあなたが可能性のあるすべての質問/考えを答えるためにここに十分置かれていますこのデザインパターンについて。
http://en.wikipedia.org/wiki/Object_pool –