iOS - OC SingleClass 单例类

前言

  • 对于一个单例类,无论初始化单例对象多少次,在程序的整个生命周期内,只会创建一个类的实例对象,而且只要程序不被杀死,该实例对象就不会被释放,并且该对象是全局的,能够被整个系统访问到。
  • 在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在 APP 开发中我们可能在任何地方都要使用用户的信息,那么可以在登录的时候就把用户信息存放在一个文件里面,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理。
  • 有的情况下,某个类可能只能有一个实例。比如说你写了一个类用来播放音乐,那么不管任何时候只能有一个该类的实例来播放声音。再比如,一台计算机上可以连好几个打印机,但是这个计算机上的打印程序只能有一个,这里就可以通过单例模式来避免两个打印任务同时输出到打印机中,即在整个的打印过程中我只有一个打印程序的实例。
  • 特点:
    • 在内存中只有一个实例
    • 提供一个全局的访问点 -> 类方法能够方便访问
  • 目的:
    • 避免重复创建,节省内存空间。
  • 常用的的单例:
        UIApplication
        NSFileManager
        NSUserDefaults
        NSNotificationCenter
  • 单例创建中,使用 allocWithZone, copyWithZone ... 等等方法,会把所有创建第二个实例可能性全部堵死。在真正开发中,有的时候,会需要额外创建一个副本。

1、GCD 方式创建

  • 1、GCD 创建方式 1

    • 下面的创建方式保证了用户除了可以通过 sharedManager 方法创建实例外,还可以通过 alloc、copy 方法创建不同的实例。

          // SingleClass.h
      
              #import <Foundation/Foundation.h>
      
              @property (nonatomic, copy)NSString *text;
      
              // 声明单例的类方法
              + (instancetype)sharedManager;
      
              @end
      
          // SingleClass.m
      
              #import "SingleClass.h"
      
              @implementation SingleClass
      
              + (instancetype)sharedManager{
      
                  // 创建静态单例类对象
                  static id instance = nil;
      
                  // 执行且在整个程序的声明周期中,仅执行一次某一个 block 对象
                  static dispatch_once_t onceToken;
                  dispatch_once(&onceToken, ^{
      
                      // 初始化单例类对象
                      instance = [[self alloc] init];
                  });
                  return instance;
              }
      
              @end
          // 单例类对象的调用
      
              // 创建单例类对象
              SingleClass *single1 = [SingleClass sharedManager];
      
              // 赋值
              single1.text = @"Hello World";
      
              // 取值
              NSString *string1 = [SingleClass sharedManager].text;
  • 2、GCD 创建方式 2
    • 下面的创建方式保证了用户不管是通过 sharedManager 方法,还是 alloc、copy 方法得到的实例都是一样的。

          static id instance = nil;
      
          + (instancetype)sharedManager {
      
              static dispatch_once_t onceToken;
              dispatch_once(&onceToken, ^{
                  instance = [[self alloc] init];
              });
              return instance;
          }
      
          + (instancetype)allocWithZone:(struct _NSZone *)zone {
      
              static dispatch_once_t onceToken;
              dispatch_once(&onceToken, ^{
                  instance = [super allocWithZone:zone];
              });
              return instance;
          }
      
          - (id)copyWithZone:(NSZone *)zone {
              return instance;
          }
      
          - (id)mutableCopyWithZone:(NSZone *)zone {
              return instance;
          }

2、互斥锁方式创建

  • 互斥锁会影响性能,所以最好还是使用 GCD 方式创建单例。
  • 1、互斥锁 创建方式 1
    • 下面的创建方式保证了用户除了可以通过 sharedManager 方法创建实例外,还可以通过 alloc、copy 方法创建不同的实例。

          // SingleClass.h
      
              #import <Foundation/Foundation.h>
      
              @property (nonatomic, copy)NSString *text;
      
              // 声明单例的类方法
              + (instancetype)defaultManager;
      
              @end
      
          // SingleClass.m
      
              #import "SingleClass.h"
      
              @implementation SingleClass
      
              + (instancetype)defaultManager{
      
                  // 创建静态单例类对象
                  static id instance = nil;
      
                  // @synchronized 同一时刻,只能有一个线程来执行 {} 中的代码
                  @synchronized(self){
      
                      if (!instance) {
      
                          // 初始化单例类对象
                          instance = [[self alloc] init];
                      }
                  }
                  return instance;
              }
      
              @end
          // 单例类对象的调用
      
              // 创建单例类对象
              SingleClass *single2 = [SingleClass defaultManager];
      
              // 赋值
              single2.text = @"Hello World";
      
              // 取值
              NSString *string2 = [SingleClass defaultManager].text;
  • 2、互斥锁 创建方式 2
    • 下面的创建方式保证了用户不管是通过 sharedManager 方法,还是 alloc、copy 方法得到的实例都是一样的。

          static id instance = nil;
      
          + (instancetype)defaultManager {
      
              @synchronized(self) {
                  if (instance == nil) {
                      instance = [[self alloc] init];
                  }
              }
              return instance;
          }
      
          + (instancetype)allocWithZone:(struct _NSZone *)zone {
      
              @synchronized(self) {
                  if (instance == nil) {
                      instance = [super allocWithZone:zone];
                  }
              }
              return instance;
          }
      
          - (id)copyWithZone:(NSZone *)zone {
              return instance;
          }
      
          - (id)mutableCopyWithZone:(NSZone *)zone {
              return instance;
          }
时间: 2024-09-20 00:27:03

iOS - OC SingleClass 单例类的相关文章

iOS - Swift SingleClass 单例类

前言 单例对象能够被整个程序所操作.对于一个单例类,无论初始化单例对象多少次,也只能有一个单例对象存在,并且该对象是全局的,能够被整个系统访问到. 单例类的创建 1.1 单例类的创建 1 单例类的创建 class SingleClass1 { var text:String = "default" class var sharedInstance: SingleClass1 { struct Static { static var onceToken: dispatch_once_t

PHP里的单例类写法实例_php实例

PHP里的单实例类在进行数据交换,节省内存上还是很有意义的.写个简单例子. 类1,单实例类本身: class UTIL { private static $instance; public function get() { if (!self::$instance) { self::$instance = new UTIL(); } return self::$instance; } public $number = 10; public function change($num) { $thi

PHP里的单例类写法实例

  这篇文章主要介绍了PHP里的单例类写法实例,本文直接给出代码实例,需要的朋友可以参考下 PHP里的单实例类在进行数据交换,节省内存上还是很有意义的.写个简单例子. 类1,单实例类本身: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class UTIL { private static $instance; public function get() { if (!self::$instance) { self::$instance = new UTIL(

关于将socket对象作为单例类的成员变量

问题描述 业务场景:1.系统在初始化时创建Socket对象(客户端)2.将创建的Socket对象作为系统全局变量,共其他方法使用.我的实现思路方法大致如下://系统初始化类publicclassInitialize{publicvoidinit(){Socketsocket=newSocket(ipAddress,port);//创建socket连接SocketSingleIntancessi=SocketSingleIntance.getSingleIntance();//将socket交由单

iOS利用单例实现不同界面间的数据传输

  首先写一个单例类,继承NSObject check.h文件中 @property(strong ,nonatomic) UITable * Table; @property(strong ,nonitomic) UITextFiled * Text; +(check*)shareDataModle; check.m中 //定义一个静态的checke类的对象,并赋给一个空值 static check * dataModle = nil; +(check*)shareDataModle { if

iOS中类单例方法的一种实现

在Cocos2D编程中,很多情况我们需要类只生成一个实例,这称之为该类的单例类. 一般我们在类中这样实现单例方法: +(instancetype)sharedInstance{ static Foo *sharedInstance; if(!sharedInstance){ sharedInstance = [Foo new]; } return sharedInstance; } 注意静态变量sharedInstance也可以放到类外部去. 但是如果是多线程环境中,上述方法并不能一定保证生成唯

iOS - OC NSNull 空值

前言 @interface NSNull : NSObject <NSCopying, NSSecureCoding> 作为占据空间的一个空值,如用在数组或字典中占据一个没有任何值的空间. NULL & nil 的区别: nil 是 OC 的,空对象,地址指向空的对象,指针地址指向的是 NULL. 在 OC 中,可以给空对象(nil)发送任何消息,不会出现错误. NULL 是 C 的,空地址,地址的数值是 0,是一个长整数. 表示地址是空,不能给 NULL 消息. 从 Xcode 6

设计模式C#描述——单例与多例模式

设计 设计模式C#描述--单例与多例模式 作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类. 单例模式有以下特点: 单例类只能有一个实例. 单例类必须自己创建自己的唯一实例. 单例类必须给所有其他对象提供这一实例. 一个典型的单例类的实现如下所示:其中构造子私有表示子类不能被继承. public class Singleton { private static Singleton m_instance = null; private

设计模式C#描述-单例与多例模式

作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类. 单例模式有以下特点: 单例类只能有一个实例. 单例类必须自己创建自己的唯一实例. 单例类必须给所有其他对象提供这一实例. 一个典型的单例类的实现如下所示:其中构造子私有表示子类不能被继承. public class Singleton{private static Singleton m_instance = null; private Singleton(){}public sta