zoukankan      html  css  js  c++  java
  • Objective-C在ARC下结合GCD的单例模式和宏模版

    单例模式在iOS开发过程中经常用到,苹果提供过objective c单例的比较官方的写法:

    static MyGizmoClass *sharedGizmoManager = nil;
     
    + (MyGizmoClass*)sharedManager
    {
        @synchronized(self) {
            if (sharedGizmoManager == nil) {
                [[self alloc] init]; // assignment not done here
            }
        }
        return sharedGizmoManager;
    }
     
    + (id)allocWithZone:(NSZone *)zone
    {
        @synchronized(self) {
            if (sharedGizmoManager == nil) {
                sharedGizmoManager = [super allocWithZone:zone];
                return sharedGizmoManager;  // assignment and return on first allocation
            }
        }
        return nil; //on subsequent allocation attempts return nil
    }
     
    - (id)copyWithZone:(NSZone *)zone
    {
        return self;
    }
     
    - (id)retain
    {
        return self;
    }
     
    - (unsigned)retainCount
    {
        return UINT_MAX;  //denotes an object that cannot be released
    }
     
    - (void)release
    {
        //do nothing
    }
     
    - (id)autorelease
    {
        return self;
    }
    


    现在iOS5之后普遍使用了ARC技术,原来这个写法就显得很累赘了,release已经不使用了。

    咱们可以结合GCD来实现单例模式:

    + (id)sharedInstance
    {
      static dispatch_once_t pred = 0;
      __strong static id _sharedObject = nil;
      dispatch_once(&pred, ^{
        _sharedObject = [[self alloc] init]; // or some other init method
      });
      return _sharedObject;
    }
    

    使用dispatch_once,这个方法的意思是在应用程序生命周期内,这方法只执行一次,这就是ARC下结合GCD的一个单例的代码

    因为我们可能需要多个单例的类,每个都写一次比较麻烦,可以更方便一些,把这些代码写成宏的形式,只需要传入类名就可以创建一个单例的类了。

    通过传入类名创建头文件中单例方法的名称:

    #define DEFINE_SINGLETON_FOR_HEADER(className) 
    
    + (className *)shared##className;
    

    通过传入类名创建单例方法的实现

    #define DEFINE_SINGLETON_FOR_CLASS(className) 
    
    + (className *)shared##className { 
    static className *shared##className = nil; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
    shared##className = [[self alloc] init]; 
    }); 
    return shared##className; 
    }
    


    使用宏:

    在项目中新建了一个类testSingleton,并且有.h 和.m文件。

    .h

    .m中的代码:

    #import "testSingleton.h"
    
    @implementation testSingleton
    DEFINE_SINGLETON_FOR_CLASS(testSingleton)
    @end
    
    #define DEFINE_SINGLETON_FOR_HEADER(className) 
    
    + (className *)shared##className;
    
    #define DEFINE_SINGLETON_FOR_CLASS(className) 
    
    + (className *)shared##className { 
    static className *shared##className = nil; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
    shared##className = [[self alloc] init]; 
    }); 
    return shared##className; 
    }
    
    #import <Foundation/Foundation.h>
    
    @interface testSingleton : NSObject
    DEFINE_SINGLETON_FOR_HEADER(testSingleton);
    @end
    

    你可以把宏单独放到项目管理宏的文件中。这里是为了方便演示放到和testSingleton.h文件了。
    获取单例:

    - (void)test
    {
        testSingleton *testShare = [testSingleton sharedtestSingleton];
    }
    
  • 相关阅读:
    JavaScript变量和作用域
    遥感专业词汇
    linux修改文件所属用户和用户组
    当singleton Bean依赖propotype Bean,可以使用在配置Bean添加look-method来解决
    linux中的目录和文件的统计
    linux命令在文件中根据命令查找
    走进ELK原理
    nohub和重定向文件
    HashMap与TreeMap按照key和value排序
    List自定义排序
  • 原文地址:https://www.cnblogs.com/lingzhao/p/3399177.html
Copyright © 2011-2022 走看看