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

简介:

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

大家都知道,使用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

测试图例:

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

目录
相关文章
|
6月前
|
前端开发
67 # 对象的处理
67 # 对象的处理
17 0
|
7月前
|
存储 程序员 编译器
C++都有对象了,你还没有吗?
C++都有对象了,你还没有吗?
52 0
|
8月前
|
Java 开发者 容器
你有对象吗?
你有对象吗?
71 0
|
存储 编译器 C语言
我现在必须new一个对象!!!
C++内存管理,手动开辟空间,我现在必须new一个对象!!!
60 0
我现在必须new一个对象!!!
|
算法 Java
对象的比较
本篇文章是对Java中一些常见的比较的总结,在涉及到比较方面,有元素的比较与对象的比较,下边博主来带领大家一起了解这些比较方式。
76 0
|
缓存 Java 关系型数据库
强引用、软引用、弱引用、幻象引用有什么区别和使用场景
强引用、软引用、弱引用、幻象引用有什么区别和使用场景
155 1
实例化可变字典对象
实例化可变字典对象
89 0
5、对象
对象就是一组“键值对”(key-value)的集合,是一种无序的复合数据集合。
93 0