首页 > 代码库 > 设计一个不强引用对象的单例字典

设计一个不强引用对象的单例字典

设计一个不强引用对象的单例字典

大家都知道,使用NSDictionary存储对象的时候会强引用对象,导致被存储对象的引用计数+1,有时候,我们想用单例来存储对象,但又不希望强引用存储的对象,这该怎么实现呢?

在这里,我们可以使用NSMapTable来实现这个功能.

我直接给出源码:

WeakDictionary.h   +   WeakDictionary.m

////  WeakDictionary.h//  弱引用字典////  http://www.cnblogs.com/YouXianMing///  Copyright (c) 2014年 Y.X. All rights reserved.//#import <Foundation/Foundation.h>#define GET_WEAK_OBJECT(key)                 [WeakDictionary objectForKey:(key)]#define REGISTER_WEAK_OBJECT(object, key)    [WeakDictionary addObject:(object) forKey:(key)]@interface WeakDictionary : NSObject+ (void)addObject:(id)object forKey:(NSString *)key;+ (id)objectForKey:(NSString *)key;@end
////  WeakDictionary.m//  弱引用字典////  http://www.cnblogs.com/YouXianMing///  Copyright (c) 2014年 Y.X. All rights reserved.//#import "WeakDictionary.h"static NSMapTable  *weakDictionary = nil;@implementation WeakDictionary+ (void)initialize{    if (self == [WeakDictionary class])    {        // 强引用key值弱引用object        weakDictionary = [NSMapTable strongToWeakObjectsMapTable];    }}+ (void)addObject:(id)object forKey:(NSString *)key{    if (object == nil || key == nil)    {        NSLog(@"object & key should not be nil.");        return;    }        if ([weakDictionary objectForKey:key] == nil)    {        [weakDictionary setObject:object forKey:key];    }}+ (id)objectForKey:(NSString *)key{    return [weakDictionary objectForKey:key];}@end

测试代码:

////  AppDelegate.m//  WeakDic////  Copyright (c) 2014年 Y.X. All rights reserved.//#import "AppDelegate.h"#import "WeakDictionary.h"#import "YXGCD.h"#import "Model.h"@interface AppDelegate ()@property (nonatomic, strong) Model    *model;@property (nonatomic, strong) GCDTimer *timer;@end@implementation AppDelegate- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{    // 创建临时model    Model *tmp = [Model new];        // 注册弱引用对象    REGISTER_WEAK_OBJECT(tmp, @"Model");        // 通过属性持有这个临时model    self.model = tmp;        // 7s之后这个属性持有另外一个model(原先model被释放了)    [[GCDQueue mainQueue] execute:^{        self.model = [Model new];    } afterDelay:NSEC_PER_SEC*7];        // 启动定时器监测临时model    _timer = [[GCDTimer alloc] initInQueue:[GCDQueue mainQueue]];    [_timer event:^{        NSLog(@"%@", GET_WEAK_OBJECT(@"Model"));    } timeInterval:NSEC_PER_SEC];    [_timer start];        return YES;}@end

测试图例:

至于为何要设计出这么一种单例出来,这种不增加对象引用计数却能持有对象的单例,你想想能有什么用处呢:)