zoukankan      html  css  js  c++  java
  • 静态变量和单例模式

    静态变量和单例模式

    1.静态变量

    静态变量Static Variable)在计算机编程领域指在程序执行前系统就为之静态分配(也即在运行时不再改变分配情况)存储空间的一类变量。与之相对应的是在运行时只暂时存在的自动变量(即局部变量)与以动态分配方式获取存储空间的一些对象,其中自动变量的存储空间在调用栈上分配与释放。

    不同情况下的作用

    除明确标识出变量的生命周期外,将变量声明为static存储类还会根据变量属性不同而有一些特殊的作用:

    • 对于静态全局变量来说,针对某一源文件的以static声明的文件级变量与函数的作用域只限于文件内(只在文件内可见),也即“内部连接”,因而可以用来限定变量的作用域;
    • 对于静态局部变量来说,在函数内以static声明的变量虽然与自动局部变量的作用域相同(即作用域都只限于函数内),但存储空间是以静态分配而非默认的自动分配方式获取的,因而存储空间所在区域不同(一般来说,静态分配时存储空间于编译时在程序数据段分配,一次分配全程有效;而自动分配时存储空间则是于调用栈上分配,只在调用时分配与释放),且两次调用间变量值始终保持一致;
    • 对于静态成员变量来说,在C++中,在类的定义中以static声明的成员变量属于类变量,也即在所有类实例中共享,与之相对的就是过程变量。

    C示例

    在C语言中,带有静态变量的程序如下所示:

    #include <stdio.h>
     
    void func() {
        static int x = 0; // 在对func的三次调用中,x只进行一次初始化
        printf("%d
    ", x); // 输出x的值
        x = x + 1;
    }
     
    int main(int argc, char * const argv[]) {
        func(); // 输出0
        func(); // 输出1
        func(); // 输出2
        return 0;
    }

    2.单例模式

      一个单例的类,无论一个应用请求它多少次,都将返回一个相同的实例。一个典型的类允许调用者创建很多实例,而对于单例类来说,一个进程中只能有一个类的实例。一个单例对象提供了全局访问其类的资源的点。单例常被用在这种单点控制被满足的情况下,例如一些类需要提供公用的服务或者资源。

     

    你应该从一个单例类的工厂方法中获得一个全局实例。当第一次被请求的时候这个类应该懒加载一个唯一的实例,并且保证之后没有其他实例被创建。。一个单例类同时也组织调用者对它实例进行copying,retaining,或者releasing。

    在一些Cocoa的框架中用到单例。其中有,NSFileManager,NSWorkspace。在UIKit,UIApplication 和 UIAccelerometer也用到单例。工厂方法以sharedClassType这种名字,方便的返回一个单例对象。例如,在Cocoa框架中,sharedFileManager,sharedColorPanel,sharedWorkspace。

     

     3. IOS中单例的创建

      有了上面的知识,我们就比较容易理解单例的创建方式了。首先介绍两种单例的创建方式。

    static AccountManager *DefaultManager = nil;
     
    + (AccountManager *)defaultManager {
        if (!DefaultManager) DefaultManager = [[self allocWithZone:NULL] init];
        return DefaultManager;
    }

    在iOS4之后有了另外一种写法:

    + (AccountManager *)sharedManager
    {
            static AccountManager *sharedAccountManagerInstance = nil;
            static dispatch_once_t predicate;
            dispatch_once(&predicate, ^{
                    sharedAccountManagerInstance = [[self alloc] init]; 
            });
        return sharedAccountManagerInstance;
    }

      无论上面的方法被调用几次,静态变量总初始化一次。关于dispatch_once这个方法,官方是这样说的:在一个应用的生命周期中执行一个block对象一次且仅一次。predicate参数是一个指向dispatch_once_t结构的指针,用来判断block有没有被完成执行。block参数是那个被执行一次的块。dispatch_once这个函数对于初始化一个应用中的全局数据如单例是很有用的。在使用block块中初始化的变量的时候,需要首先调用这个函数。如果在多线程情况下同时调用,这个函数同步等待block块中的内容执行完毕。predicate必须指向一个全局或静态变量。 

  • 相关阅读:
    FineUI官方论坛出现空白页的解决办法!
    【三石jQuery视频教程】03.创建垂直时间表(Timeline)
    【三石jQuery视频教程】02.创建 FontAwesome 复选框和单选框
    【三石jQuery视频教程】01.图片循环展示_再次重发
    【三石jQuery视频教程】01.图片循环展示
    FineUI小技巧(7)多表头表格导出
    FineUI(专业版)实现百变通知框(无JavaScript代码)!
    FineUI(专业版)v1.2.0 和 FineUI(开源版)v4.1.1 同时发布!
    FineUI(专业版)新增 5 款 Metro 皮肤,邀您共赏!
    FineUI(专业版)公测版发布(这速度,真TM快!)
  • 原文地址:https://www.cnblogs.com/wantyoulee/p/4390715.html
Copyright © 2011-2022 走看看