Skip to content

Instantly share code, notes, and snippets.

@chrishulbert
Created June 21, 2011 04:18
Show Gist options
  • Save chrishulbert/1037232 to your computer and use it in GitHub Desktop.
Save chrishulbert/1037232 to your computer and use it in GitHub Desktop.
NSMutableSet with weak references eg doesn't retain added objects
// WeakReferenceSet.h
// Created by chris.hulbert@gmail.com on 21/06/11.
#import <Foundation/Foundation.h>
@interface WeakReferenceSet : NSObject
+ (WeakReferenceSet*)set;
- (void)addObject:(id)object;
- (void)removeObject:(id)object;
- (void)removeAllObjects;
- (NSArray *)allObjects;
@end
// WeakReferenceSet.m
// Created by Chris (chris.hulbert@gmail.com) on 21/06/11.
#import "WeakReferenceSet.h"
// Declaration of private properties
@interface WeakReferenceSet()
@property (nonatomic,retain) NSMutableSet *internalSet;
@end
@implementation WeakReferenceSet
@synthesize internalSet=_internalSet;
// Dealloc, freeing everything from the list without affecting their retain count
-(void)dealloc {
[self removeAllObjects]; // So that the normal nsmutableset's dealloc doesn't release them all
self.internalSet = nil;
[super dealloc];
}
// Constructor
-(id)init {
self = [super init];
if (self) {
self.internalSet = [NSMutableSet set];
}
return self;
}
// Creates an autoreleased weak reference set
+(WeakReferenceSet *)set {
return [[[self alloc] init] autorelease];
}
// Remove everything
- (void)removeAllObjects {
while (self.internalSet.count) {
[self removeObject:self.internalSet.anyObject];
}
}
// Adds an object to the set, however does not allow the reference count to be incremented, as we wish to have a weak reference
-(void)addObject:(id)object {
if (![self.internalSet containsObject:object]) {
[self.internalSet addObject:object]; // This will do a retain
[object release]; // So here, we release it to counter the retain
}
}
// Removes an object from the set, countering the normal release that this triggers
-(void)removeObject:(id)object {
if ([self.internalSet containsObject:object]) {
[object retain]; // Do a retain, to counter the release that follows
[self.internalSet removeObject:object]; // This does a release
}
}
// Access the list of objects so that you can iterate through it and eg send your observers a message
-(NSArray *)allObjects {
return self.internalSet.allObjects;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment