Permalink
Browse files

Avoid using NSHashTable

Makes AppNetKit at least theoretically compatible with iOS 5 and Lion.
  • Loading branch information...
brentdax committed Oct 28, 2012
1 parent 80b8e31 commit c29e0a75440671a1ebf8f7e1315d8d37634dc12a
Showing with 64 additions and 5 deletions.
  1. +64 −5 _ANIdentifiedResourceSet.m
View
@@ -8,31 +8,90 @@
#import "_ANIdentifiedResourceSet.h"
+// Basically just a safer version of +[NSValue valueWithNonretainedObject:]
+@interface _ANWeakReference : NSObject
+
++ (id)weakReferenceWithReferent:(id)referent;
+- (id)initWithReferent:(id)referent;
+
+@property (nonatomic,readonly,weak) id referent;
+
+@end
+
@interface _ANIdentifiedResourceSet ()
-@property (strong,nonatomic) NSHashTable * resources;
+@property (strong,nonatomic) NSMutableDictionary * resources;
@end
@implementation _ANIdentifiedResourceSet
- (id)init {
if((self = [super init])) {
- _resources = [NSHashTable weakObjectsHashTable];
+ _resources = [NSMutableDictionary new];
}
return self;
}
- (void)addResource:(ANIdentifiedResource *)resource {
- [self.resources addObject:resource];
+ _ANWeakReference * ref = [_ANWeakReference weakReferenceWithReferent:resource];
+
+ NSMutableDictionary * resourcesByID = [self resourcesByIDForClassOfResource:resource];
+ id <NSCopying> IDKey = [self IDKeyForIdentifiedResource:resource];
+ [resourcesByID setObject:ref forKey:IDKey];
}
- (ANIdentifiedResource *)existingResource:(ANIdentifiedResource *)resource {
- return [self.resources member:resource];
+ NSDictionary * resourcesByID = [self resourcesByIDForClassOfResource:resource];
+ id <NSCopying> IDKey = [self IDKeyForIdentifiedResource:resource];
+ _ANWeakReference * resourceReference = [resourcesByID objectForKey:IDKey];
+
+ return resourceReference.referent;
}
- (void)removeResource:(ANIdentifiedResource *)resource {
- [self.resources removeObject:resource];
+ if([self existingResource:resource] != resource) {
+ return;
+ }
+
+ NSMutableDictionary * resourcesByID = [self resourcesByIDForClassOfResource:resource];
+ id <NSCopying> IDKey = [self IDKeyForIdentifiedResource:resource];
+ [resourcesByID removeObjectForKey:IDKey];
+}
+
+- (id <NSCopying>)classKeyForIdentifiedResource:(ANIdentifiedResource*)resource {
+ return NSStringFromClass(resource.class);
+}
+
+- (id <NSCopying>)IDKeyForIdentifiedResource:(ANIdentifiedResource*)resource {
+ return [NSNumber numberWithUnsignedLongLong:resource.ID];
+}
+
+- (NSMutableDictionary*)resourcesByIDForClassOfResource:(ANIdentifiedResource*)resource {
+ id <NSCopying> classKey = [self classKeyForIdentifiedResource:resource];
+
+ NSMutableDictionary * resourcesByID = [self.resources objectForKey:classKey];
+ if(!resourcesByID) {
+ resourcesByID = [NSMutableDictionary new];
+ [self.resources setObject:resourcesByID forKey:classKey];
+ }
+
+ return resourcesByID;
+}
+
+@end
+
+@implementation _ANWeakReference
+
++ (id)weakReferenceWithReferent:(id)referent {
+ return [[self alloc] initWithReferent:referent];
+}
+
+- (id)initWithReferent:(id)referent {
+ if((self = [super init])) {
+ _referent = referent;
+ }
+ return self;
}
@end

0 comments on commit c29e0a7

Please sign in to comment.