单例模式
    在建模的时候,如果这个东西确实只需要一个对象,多余的对象都是无意义的,那么就考虑用单例模式。比如定位管理(CLLocationManager),硬件设备就只有一  个,弄再多的逻辑对象意义不大。所以就会考虑用单例
        1) 系统为我们提供的单例类有哪些?
              UIApplication(应用程序实例类)
              NSNotificationCenter(消息中心类)
              NSFileManager(文件管理类)
              NSUserDefaults(应用程序设置)
              NSURLCache(请求缓存类)
              NSHTTPCookieStorage(应用程序cookies池)
        2) iOS单例的创建

a. 单例类需要保证只有一个实例,因此在第一次访问这个实例的时候才创建,之后访问直接取已经创建好的实例

+(instancetype)shareInstance {

              static Singleton *singleteon;

              if (!singleteon ) {

                   singleteon = [[Singleton alloc] init];

               }

               return singleteon;

         }

单线程单例存在一些弊端,在多线程的情况下,会产生线程不安全的情况。严格意义上来说,我们还需要把alloc方法变为私有方法才行,严格的单例是

不允许再创建其他实例的,而alloc方法可以在外部任意生成实例。但是考虑到alloc属于NSObject,iOS中无法将alloc变成私有方法,最多只能覆盖alloc

让其返回空。不过个人不建议这么做,一般情况下对alloc不做特殊处理。系统的单例也未对alloc做任何处理.

b. @synchronized单例

上面单线程单例,在多线程情况下,可能会出现一些问题。如果两个线程同时调用shareInstanc,可能会创建出2个singleton出来。所以在对多线程情况下,

我们需要使用@synchronize来加锁.

+(instancetype)shareInstance {

               static Singleton *singleton;

               @synchronized (self) {

                    if (!singleton) {

                           singleton = [[Singleton alloc] init];

                    }   

                }

                return singleton;

          }

加锁以后,当多个线程同时调用shareInstance时,由于@synchronized已经加锁,只能有一个线程创建singleton实例。这样就解决了多线程调用单例的问题。

c.dispatch_once单例

使用@synchronized虽然一定程度上解决了多线程的问题,但并不完美。因为只有在singleton未创建时,加锁才是必要的。如果singleton已经创建,这个时

候还加锁的话,会影响性能。
              
在iOS中,GCD为我们提供方便又高效的方法—dispatch_once

        +(instancetype)shareInstance{
static Singleton *singleton;
static dispatch_once_t onceToken; //1.onceToken = 0;
dispatch_once(&onceToken,^{
NSLog(@"%ld",onceToken); //2.onceToken = 140734537148864
singleton = [[Singleton alloc] init];
});
NSLog(@"%ld",onceToken); //3.onceToken = -1
return singleton;
}

               dispatch_once为什么能做到既解决同步多线程问题

               dispatch_once的原理:
               dispatch_once主要是根据onceToken的值来决定怎么去执行代码。
               1.当onceToken = 0时,线程执行dispatch_onceblock中代码
               2.当onceToken = -1时,线程跳过dispatch_onceblock中代码不执行
               3.当onceToken为其他值时,线程被阻塞,等待onceToken值改变
               当线程调用shareInstance,此时onceToken = 0,调用block中的代码,此时onceToken的值变为140734537148864。当其他线程再调用shareInstance

方法时,onceToken的值已经是140734537148864了,线程阻塞。当block线程执行完block之后,onceToken变为-1.其他线程不再阻塞,跳过block

下次再调用shareInstance时,block已经为-1.直接跳过block

 

ios 单例的再次理解的更多相关文章

  1. 【iOS 单例设计模式】底层解析与运用

    [iOS 单例设计模式]底层解析与运用 一.单例设计名词解释: (官方解释)单例模式确保一个类只有一个实例,自行提供这个实例并向整个系统提供这个实例.(形象比喻)程序 — 公司   单例实例 - 管理 ...

  2. iOS单例创建的一点疑惑

    线程安全的单例常用写法, +(AccountManager *)sharedManager{ static AccountManager *defaultManager = nil; disptch_ ...

  3. iOS单例设计模式具体解说(单例设计模式不断完好的过程)

    在iOS中有非常多的设计模式,有一本书<Elements of Reusable Object-Oriented Software>(中文名字为<设计模式>)讲述了23种软件设 ...

  4. iOS 单例传值遇见问题

    单例模式的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类. 1.单例模式的要点: 显然单例模式的要点有三个:一是某个类只能有一个实例: ...

  5. iOS单例的两种实现

    单例模式算是开发中比较常见的一种模式了.在iOS中,单例有两种实现方式(至少我目前只发现两种).根据线程安全的实现来区分,一种是使用@synchronized,另一种是使用GCD的dispatch_o ...

  6. iOS 单例用法

    单例模式的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类. 1.单例模式的要点: 显然单例模式的要点有三个:一是某个类只能有一个实例: ...

  7. iOS单例详解

    单例:整个程序只创建一次,全局共用. 单例的创建 // SharedPerson.h 文件中 + (instancetype)share; // SharedPerson.m 文件中 static S ...

  8. ios 单例设计模式

    单例模式的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类.单例可用性非常高,用于登录用户管理等可供全局调用. + (AccountMa ...

  9. iOS 单例的销毁

    今天做项目的时候,对于不同的用户,需要创建不同的数据库.但是退出登录切换账号时,因为用单例创建数据,导致切换账号不会切换数据.所以,需要销毁单例.销毁单例时,调用以下的代码: 在创建单例的那个类中,调 ...

随机推荐

  1. css 实现多行文本末尾显示省略号

    思路: 省略号使用绝对定位添加,开头部分避免突兀使用c3渐变背景颜色 <!DOCTYPE html> <html lang="en"> <head&g ...

  2. 深度森林DeepForest

    级联森林(Cascade Forest) 级联森林结构的图示.级联的每个级别包括两个随机森林(蓝色字体标出)和两个完全随机树木森林(黑色). 假设有三个类要预测,因此,每个森林将输出三维类向量,然后将 ...

  3. html5 + shiro

    偶然与巧合 舞动了蝶翼 谁的心头风起 前赴而后继 万千人追寻 荒漠唯一菩提 似擦肩相遇 或擦肩而去 命运犹如险棋 无数时间线 无数可能性 终于交织向你

  4. 杂谈3.py

    bin() --------十转二 hex()------- 十转十六 oct()-------十转八 import math math.floor(数值)返回小于等于数值的整数 math.trunc ...

  5. php解析excel文件

    public static function getStaffByXlsx($path) { /*dirname(__file__): 当前代码所在的目录,$path: ”/文件名“ */ $PHPR ...

  6. leetcode19

    class Solution { public: ; ; ListNode* removeNthFromEnd(ListNode* head, int n) { ; ListNode* node = ...

  7. HTML5-canvas1.0

    HTML5 <canvas> 元素用于图形的绘制,通过脚本 (通常是JavaScript)来完成.<canvas> 标签只是图形容器,您必须使用脚本来绘制图形.你可以通过多种方 ...

  8. JEECG-Swagger UI的使用说明

    一.代码生成 (此步骤为代码生成器的使用,如不清楚请查阅相关文档视频) 1.进入菜单[在线开发]-->[Online表单开发],选中一张单表/主表,点击代码生成按钮. 2.弹出页面中填写代码生成 ...

  9. 转:java使用Filter过滤器对Response返回值进行修改

    练习时只做了对request 的处理,这里记录一下,filter 对 response的处理. 原文地址:java使用Filter过滤器对Response返回值进行修改 有时候在开发过程中会有这样一个 ...

  10. 一分钟搭建Spring Boot

    1.首先你的电脑需要安装jdk.Apache Maven.Intellij IDEA 2.新建项目  (敲重点,有的同学有没有Spring Initializr 这个请到本文章后面看安装步骤) 3.选 ...