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];