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


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

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

    测试图例:

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

  • 相关阅读:
    过河问题 (Standard IO)
    单词分类 (Standard IO)
    C#综合揭秘——细说多线程(上)
    使用NPOI导入导出标准Excel
    C# 转义字符 ''反斜杠
    ref和out的区别
    抽象类接口的区别
    方法签名
    SQL Server的通用分页存储过程 未使用游标,速度更快!
    SQL Server存储过程Return、output参数及使用技巧
  • 原文地址:https://www.cnblogs.com/YouXianMing/p/3889422.html
Copyright © 2020-2023  润新知