diff --git a/GSCache.h b/GSCache.h
index a5510ea..beed981 100644
--- a/GSCache.h
+++ b/GSCache.h
@@ -140,6 +140,17 @@
*/
- (void) purge;
+/**
+ * Similar to -setObject:forKey:lifetime: but, if there is an existing
+ * object in the cache which -isEqual: to anObject (or is anObject is nil),
+ * the existing object is retained in the cache (though its lifetime is
+ * updated/refreshed).
+ * The value of the object in the cache is returned.
+ */
+- (id) refreshObject: (id)anObject
+ forKey: (id)aKey
+ lifetime: (unsigned)lifetime;
+
/**
* Sets the delegate for the receiver.
* The delegate object is not retained.
diff --git a/GSCache.m b/GSCache.m
index aebce31..aa583f1 100644
--- a/GSCache.m
+++ b/GSCache.m
@@ -537,6 +537,46 @@ static void removeItem(GSCacheItem *item, GSCacheItem **first)
}
}
+- (id) refreshObject: (id)anObject
+ forKey: (id)aKey
+ lifetime: (unsigned)lifetime
+{
+ id object;
+ GSCacheItem *item;
+
+ [my->lock lock];
+ item = (GSCacheItem*)NSMapGet(my->contents, aKey);
+ if (item == nil)
+ {
+ if (nil != anObject)
+ {
+ [self setObject: anObject
+ forKey: aKey
+ lifetime: lifetime];
+ }
+ [my->lock unlock];
+ return anObject;
+ }
+
+ if (nil != anObject && NO == [anObject isEqual: item->object])
+ {
+ object = [anObject retain];
+ [item->object release];
+ item->object = object;
+ }
+ if (lifetime > 0)
+ {
+ unsigned tick = GSTickerTimeTick();
+
+ item->when = tick + lifetime;
+ item->warn = tick + lifetime / 2;
+ }
+ item->life = lifetime;
+ object = [[item->object retain] autorelease];
+ [my->lock unlock];
+ return object;
+}
+
- (void) setDelegate: (id)anObject
{
[my->lock lock];