Skip to content

Instantly share code, notes, and snippets.

@beccadax
Created August 26, 2012 02:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save beccadax/3473115 to your computer and use it in GitHub Desktop.
Save beccadax/3473115 to your computer and use it in GitHub Desktop.
Suggested code to get rid of objects with no references except for their presence in a specific set
// self.resources is an NSMutableSet of ANResource objects.
// I want to remove the objects that have no other references in the app.
// (This is intended to be called in response to an iOS memory warning.)
// Will this do the trick?
- (void)discardUnusedResources {
// We pass the objects through a weak reference; if they're not
// referenced anywhere else in the app, they won't survive the journey.
NSMutableSet * newResources = [NSMutableSet new];
NSUInteger oldResourceCount = self.resources.count;
__weak ANResource * weakResource;
while((weakResource = [self.resources anyObject])) {
[self.resources removeObject:weakResource];
__strong ANResource * strongResource = weakResource;
if(strongResource) {
[newResources addObject:strongResource];
}
}
self.resources = newResources;
NSLog(@"-[ANSession discardUnusedResources]: started with %u resources, ended with %u", oldResourceCount, self.resources.count);
}
@beccadax
Copy link
Author

@belkadan, NSCache drops the entire cache on the floor under memory pressure. That's not what I want—it would lose references to objects that are still active. The main purpose of this set is not caching, but uniquing—ensuring that each of the external resources is represented by exactly one ANResource object. (Think of the way a Core Data managed object context always has exactly one object for each record—that's what I'm doing.) If I used NSCache, then a cache drop could cause a new object to be created for a resource which already has an old object, and the old object would slowly become staler and staler.

I'm using an NSHashTable for now, but I'm not really happy with that solution, because I want this code to run on iOS 5 as well as 6...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment