• 单例 singleton


    一、单例模式

    特点:单例模式的类必须保证始终只有一个实例存在。

    场景:在整个应用程序中,共享一份资源(这份资源只需要创建初始化1次),应该让这个类创建出来的对象永远只有一个。

    二、单例类的构建

    1:为你的单例类声明一个静态的实例,并且初始化它的值为nil。

    2:在获取实例的方法中,只有在静态实例为nil的时候,产生一个你的类的实例,这个实例通常被称为共享的实例。

    3:重写allocWithZone 方法,用于确定:不能够使用其他的方法来创建我们不得实例,限制用户只能通过获取实例的方法得到这个类的实例。所以,我们在allocWithZone方法中直接返回共享的类实例。

    4:实现基本的协议方法 copyWithZone、release、retain、retainCount 和 autorelease,用于保证单例具有一个正确的状态。(MRC下)非arc

    5:在init方法中初始化一些东西

    三、多线程下的单例

    使用@sychronized(){}指令

    四、栗子

    #import <Foundation/Foundation.h>
    
    //图片管理类
    //单例类
    
    @interface ZYImageManager : NSObject
    
    + (ZYImageManager *)shareImageManager;
    
    - (void)test;
    
    @end
    #import "ZYImageManager.h"
    
    /*
     1、声明静态实例 并初始化值为nil
     2、声明静态方法 方法中判断如果实例为nil就创建
     3、重写allocWithZone方法 杜绝创建新的实例
     4、重写copyWithZone方法 防止对象copy
     5、重写引用计数相关东西 推荐
     6、init方法 初始化一些东西
     7、因为创建本类实例时 使用了alloc alloc会调用allocWithZone 然而allocWithZone又被本类重写了 所以应改为[super allocWithZone:NULL]
     8、处理多线程下的线程同步
     */
    
    //栈、堆、全局变量区(静态区)、方法区、常量区
    static ZYImageManager *singletonInstance = nil;
    static int count = 10;  // count 的作用是证明这个类只创建了一次
    
    @implementation ZYImageManager
    
    + (ZYImageManager *)shareImageManager
    {
        //@synchronized(self) 管理线程:Objective-C在应用程序中支持多任务。这意味着可能有两个线程同时试图修改同一个对象。有一个办法可以解决这个情况。为了防止多个线程同时执行同一个代码块,OC提供了@synchronized()指令。
        //使用@synchronized()指令可以锁住在线程中执行的某一个代码块。使用代码块的其他线程,将被阻塞,这也就意味着,他们将在@synchronized()代码块的最后一条语句执行结束后才能继续执行。一般在公用变量的时候使用,如单例模式或者操作类的static变量中使用。
        @synchronized(self)
        {
            if (singletonInstance == nil) {
               //调用父类方法开辟空间 参数无用
                singletonInstance = [[super allocWithZone:NULL] init]; //在NSObject 这个类的官方文档里面,allocWithZone方法介绍说,该方法的参数是被忽略的,正确的做法是传nil或者NULL参数给它。而这个方法之所以存在,是历史遗留原因。就是你不用传参就会给你开辟空间
               //而为什么不用[[ super alloc] init]那 因为这样他还会调用子类的allocwithzoon
                count++;
            }
        }
        return singletonInstance;
    }
    
    //重写初始化方法 初始化一些需要初始化的东西
    - (id)init
    {
        self = [super init];
        if (self)
        {
          
        }
        return self;
    }
    
    //分配内存
    //因为alloc会调用此方法 所以应重写防止其再创建对象
    + (id)allocWithZone:(struct _NSZone *)zone
    {
        return singletonInstance;
    }
    
    //copy时会调用此方法
    + (id)copyWithZone:(struct _NSZone *)zone
    {
        return singletonInstance;
    }
    
    //重写一下跟引用计数有关的东西 推荐
    - (id)retain
    {
        return self;
    }
    
    //重写release以及autorelease
    - (oneway void)release
    {
    
    }
    
    - (id)autorelease
    {
        return self;
    }
    
    //返回1可以 如下亦可
    - (NSUInteger)retainCount
    {
        return NSUIntegerMax;   
    }
    
    - (void)test
    {
        NSLog(@"%d", count);
    }
    @end
    View Code
    #import "ZYAppDelegate.h"
    #import "ZYImageManager.h"
    
    @implementation ZYAppDelegate
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        //测试单例
        [[ZYImageManager shareImageManager] test];
        
        ZYImageManager *imageManager = [ZYImageManager shareImageManager];
        [imageManager test];
        
        ZYImageManager *imageManager2 = [[ZYImageManager alloc] init];
    
        //查看单例内存地址  内存地址一样  没什么好说的
        NSLog(@"%@__%@", imageManager2, imageManager);
        [imageManager2 test];
        
        self.window.backgroundColor = [UIColor whiteColor];
        [self.window makeKeyAndVisible];
        return YES;
    }
    
    @end
  • 相关阅读:
    jQuery语音播放插件
    Oracle(+)号用法
    重写IHttpHandler,实现前后端分离
    JavaScript运算符
    SQL Server 备份和还原
    ReactJS入门
    用Owin Host实现脱离IIS跑Web API单元测试
    Lua
    代码评比结果的反思
    我为什么要在总理来的第二天离开创业大街(转)
  • 原文地址:https://www.cnblogs.com/hyhl23/p/4320630.html
Copyright © 2020-2023  润新知