Skip to content

Instantly share code, notes, and snippets.

@hisui
Created June 9, 2012 06:58
Show Gist options
  • Save hisui/2899891 to your computer and use it in GitHub Desktop.
Save hisui/2899891 to your computer and use it in GitHub Desktop.
Objective-C(+ARC)で弱参照キャッシュ
#import <Foundation/Foundation.h>
// QzCacheMapにキャッシュさせる為には、これを継承させる
@interface QzCacheEntry : NSObject
@end
@interface QzCacheMap : NSObject
- (id)initWithCapacity:(size_t)capacity;
// キャッシュするオブジェクトをキーに割り当てる
- (void)put:(QzCacheEntry*)entry
forKey:(NSString*)key;
// キーに対応したキャッシュ済みのオブジェクトを取得
- (id)get:(NSString*)key;
// 削除用
- (BOOL)remove:(__unsafe_unretained QzCacheEntry*)entry;
@end
#import "QzCacheMap.h"
@interface QzCacheEntry ()
{
@package
QzCacheMap *_cacheMap;
NSString *_assigned;
}
@end
@implementation QzCacheMap
{
NSMutableDictionary *_dic;
size_t _capacity;
}
- (id)initWithCapacity:(size_t)capacity
{
if((self = [self init])) {
self->_dic = [NSMutableDictionary dictionaryWithCapacity:capacity];
self->_capacity = capacity;
}
return self;
}
- (void)put:(QzCacheEntry*)entry
forKey:(NSString*)key
{
[_dic setObject:[NSNumber numberWithUnsignedLong:(uintptr_t)entry]
forKey:key];
entry->_cacheMap = self;
entry->_assigned = key;
}
- (id)get:(NSString*)key
{
NSNumber *box = [_dic objectForKey:key];
if(!box) {
return nil;
}
return (__bridge id) (void*) [box unsignedLongValue];
}
- (BOOL)remove:(__unsafe_unretained QzCacheEntry*)entry
{
// 別の人が管理してるキャッシュ
if(entry->_cacheMap != self) {
return NO;
}
NSNumber *box = [_dic objectForKey:entry->_assigned];
// エントリーが存在しない
if(!box) {
return NO;
}
// キーに割り当てられているのは別のキャッシュ
if((uintptr_t)entry != [box unsignedLongValue]) {
return NO;
}
[_dic removeObjectForKey:entry->_assigned];
return YES;
}
@end
@implementation QzCacheEntry
- (void)dealloc
{
[_cacheMap remove:self];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment