单例 singleton

一、单例模式

特点:单例模式的类必须保证始终只有一个实例存在。

场景:在整个应用程序中,共享一份资源(这份资源只需要创建初始化1次),应该让这个类创建出来的对象永远只有一个。

 

二、单例类的构建

1:为你的单例类声明一个静态的实例,并且初始化它的值为nil。

2:在获取实例的方法中,只有在静态实例为nil的时候,产生一个你的类的实例,这个实例通常被称为共享的实例。

3:重写allocWithZone 方法,用于确定:不能够使用其他的方法来创建我们不得实例,限制用户只能通过获取实例的方法得到这个类的实例。所以,我们在allocWithZone方法中直接返回共享的类实例。

4:实现基本的协议方法 copyWithZone、release、retain、retainCount 和 autorelease,用于保证单例具有一个正确的状态。(MRC下)非arc

5:在init方法中初始化一些东西

 

三、多线程下的单例

使用@sychronized(){}指令

 

四、栗子

#import <Foundation/Foundation.h>

//图片管理类
//单例类

@interface ZYImageManager : NSObject

+ (ZYImageManager *)shareImageManager;

- (void)test;

@end
#import "ZYImageManager.h"

/*
 1、声明静态实例 并初始化值为nil
 2、声明静态方法 方法中判断如果实例为nil就创建
 3、重写allocWithZone方法 杜绝创建新的实例
 4、重写copyWithZone方法 防止对象copy
 5、重写引用计数相关东西 推荐
 6、init方法 初始化一些东西
 7、因为创建本类实例时 使用了alloc alloc会调用allocWithZone 然而allocWithZone又被本类重写了 所以应改为[super allocWithZone:NULL]
 8、处理多线程下的线程同步
 */

//栈、堆、全局变量区(静态区)、方法区、常量区
static ZYImageManager *singletonInstance = nil;
static int count = 10;  // count 的作用是证明这个类只创建了一次

@implementation ZYImageManager

+ (ZYImageManager *)shareImageManager
{
    //@synchronized(self) 管理线程:Objective-C在应用程序中支持多任务。这意味着可能有两个线程同时试图修改同一个对象。有一个办法可以解决这个情况。为了防止多个线程同时执行同一个代码块,OC提供了@synchronized()指令。
    //使用@synchronized()指令可以锁住在线程中执行的某一个代码块。使用代码块的其他线程,将被阻塞,这也就意味着,他们将在@synchronized()代码块的最后一条语句执行结束后才能继续执行。一般在公用变量的时候使用,如单例模式或者操作类的static变量中使用。
    @synchronized(self)
    {
        if (singletonInstance == nil) {
           //调用父类方法开辟空间 参数无用
            singletonInstance = [[super allocWithZone:NULL] init]; //在NSObject 这个类的官方文档里面,allocWithZone方法介绍说,该方法的参数是被忽略的,正确的做法是传nil或者NULL参数给它。而这个方法之所以存在,是历史遗留原因。就是你不用传参就会给你开辟空间
           //而为什么不用[[ super alloc] init]那 因为这样他还会调用子类的allocwithzoon
            count++;
        }
    }
    return singletonInstance;
}

//重写初始化方法 初始化一些需要初始化的东西
- (id)init
{
    self = [super init];
    if (self)
    {
      
    }
    return self;
}

//分配内存
//因为alloc会调用此方法 所以应重写防止其再创建对象
+ (id)allocWithZone:(struct _NSZone *)zone
{
    return singletonInstance;
}

//copy时会调用此方法
+ (id)copyWithZone:(struct _NSZone *)zone
{
    return singletonInstance;
}

//重写一下跟引用计数有关的东西 推荐
- (id)retain
{
    return self;
}

//重写release以及autorelease
- (oneway void)release
{

}

- (id)autorelease
{
    return self;
}

//返回1可以 如下亦可
- (NSUInteger)retainCount
{
    return NSUIntegerMax;   
}

- (void)test
{
    NSLog(@"%d", count);
}
@end
View Code
#import "ZYAppDelegate.h"
#import "ZYImageManager.h"

@implementation ZYAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    //测试单例
    [[ZYImageManager shareImageManager] test];
    
    ZYImageManager *imageManager = [ZYImageManager shareImageManager];
    [imageManager test];
    
    ZYImageManager *imageManager2 = [[ZYImageManager alloc] init];

    //查看单例内存地址  内存地址一样  没什么好说的
    NSLog(@"%@__%@", imageManager2, imageManager);
    [imageManager2 test];
    
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}

@end

 

posted @ 2015-03-07 17:07  红红de  阅读(220)  评论(0编辑  收藏  举报