zoukankan      html  css  js  c++  java
  • iOS 单例

    1. 单例模式原理

    1.1. 概念

      系统中的一个类,只有一个实例,易于外界访问。

      示例:

    [[UIApplication sharedApplication] statusBarStyle];
    [NSNotificationCenter defaultCenter];
    [NSUserDefaults standardUserDefaults];
    [NSfileManager defaultManager];

    1.2. 针对解决的问题

      全局共享。

    1.3. 优缺点

      共享信息,用于管理中心。

      破坏了封装性,破坏了设计模式中的最少知识原则。

    1.4. 简单的单例

    +(instancetype)managerCenter{
         static className*center = nil;       
         if (center == nil){
             center = [[className alloc] init];   
        }      
        return center;   
    }
    

      这种方案会导致多个位置同时访问时,都会进入if逻辑里面。

      

      那么采取另外的方案:

    +(instancetype)managerCenter{
         static className*center = nil;
         static dispatch_once_t predicate;
         dispatch_once (&predicate, ^{
             center = [[className alloc] init];   
        });      
        return center;   
    }

      第三种方案:

      由于所有的类启动时都会调用+(void)initialize方法,所以,可以在里面处理:

    +(void)initialize{
        static className *center = nil;
        if(self == ([className class]){
            center = [[calssName alloc] init];
        }
    
    }    

    2. 编写严格的单例

    #import "VGPathManager.h"
    
    #pragma mark - 创建实例
    
    static VGPathManager *center = nil;
    static NSString *strClass = @"VGPathManager";
    
    @implementation VGPathManager
    
    + (instancetype)managerCenter {
        
        static dispatch_once_t predicate;
        dispatch_once(&predicate, ^{
            
            /**
             *  这么做的原因是:在 init() 中会判断是否是本类,而不是子类
             */
            center = (VGPathManager *)strClass;
            center = [[VGPathManager alloc] init];
        });
        
        if (nil != center) {
            if (FALSE == [center cantUsedBySubClass]) {
                return nil;
            }
        }
        
        return center;
    }
    
    - (instancetype)init {
        
        NSString *string = (NSString *)center;
        if ([string isKindOfClass:[NSString class]] == YES && [string isEqualToString:strClass]) {
            
            self = [super init];
            if (self) {
                if (FALSE == [self cantUsedBySubClass]) {
                    return nil;
                }
            }
            
            return self;
            
        } else {
            
            return nil;
        }
    }
    
    /**
     *  防止子类使用,如果是子类,则会是不同的名称
     */
    - (BOOL) cantUsedBySubClass {
        
        NSString *classString = NSStringFromClass([self class]);
        if ([classString isEqualToString:strClass] == NO) {
            
            return  FALSE;
        }
        
        return  TRUE;
    
    }
    
    @end
    

    2.1. 防止继承

      不允许子类也实现该实例,在请求单例的方法中的进行类的名称的判断。

    2.2. 防止多个实例

      一个类中只有一个实例,但是上面的例子并不能实现一个实例,因为还可以alloc一些实例。

    3. 例子优化存储

      用FastCoding把对象转换成NSData,然后存储到本地。 

    3.1. 用单例设计存储数据接口

      单例就不用细说了,见上面的实现。

      存储数据接口就是加上下面两个接口:

    - (void)storeValue:(id)value withKey:(NSString *)key;
    - (id) valueWithKey:(NSString *) key;

    3.2. 用单例接口隔离实现细节

    - (void)storeValue:(id)value withKey:(NSString *)key {
    
        NSParameterAssert(value);//为空则崩溃
        NSParameterAssert(key);//为空则崩溃
        
        NSData *data = [FastCoder dataWithRootObject:value];
        if (data) {
            
            [[NSUserDefaults standardUserDefaults] setObject:data forKey:key];
        }
    }
    
    - (id)valueWithKey:(NSString *)key {
    
        NSParameterAssert(key);//为空则崩溃
        
        NSData *data = [[NSUserDefaults standardUserDefaults] valueForKey:key];
        
        return [FastCoder objectWithData:data];
    }

    3.3. 在单例提供接口的寄出去进行上层封装

  • 相关阅读:
    用Python完成一个汇率转换器
    鸿蒙如何用JS开发智能手表App
    鸿蒙如何用JS开发智能手表App
    SAP Spartacus SplitViewComponent Migration 的一个具体例子
    SAP Spartacus B2B 页面 Popover Component 的条件显示逻辑
    SAP Spartacus 升级时关于 schematics 的更新
    SAP Spartacus B2B 页面 Disable 按钮的显示原理
    SAP Spartacus B2B 页面 Disable Confirmation 对话框的显示原理
    通过 Feature Level 动态控制 SAP Spartacus 的页面显示
    SAP Commerce Cloud Build Manifest Components
  • 原文地址:https://www.cnblogs.com/SimonGao/p/5010029.html
Copyright © 2011-2022 走看看