iOS中单例的总结

来源:互联网 发布:touch炫舞刷vip软件 编辑:程序博客网 时间:2024/05/18 16:35

写法总结:

1.保证线程安全的写法(加锁):用关键字@synchronized关键字,保证只有一个线程去访问初始化方法

+ (id)sharedManager{

    @synchronized(self){

        if(sharedManager == nil){

            sharedManager = [[self alloc] init];

        }

    }

return sharedManager;

}


2.GCD写法(blocks),此派遣(dispatch)只会执行一次

+ (id)sharedManager{

    static dispatch_once _t onceToken;

    dispatch_once(&onceToken, ^{

        sharedManager = [[self alloc] init];

    });

return sharedManager;

}


3.第一次实例化时候创建(Lock free免锁)

+ (voidq) initialize{

    static BOOL initialized = NO;

    if(initialized == NO){

        initialized = YES;

        sharedManager = [[self alloc] init];

    }

}

之后再重写allocWithZone:、copyWithZone:、retain、copy、release、autorelease、等方法,为了防止意外调用这几种未重写过的方法而产生另一个对象,此时就不能保证对象的唯一性和存在性了,所以要重写方法。
=====================================================================================================================


以下内容来自:http://blog.csdn.net/tskyfree/article/details/8463404


        在设计模式中有一个单例模式,对应的我们常常会设计单例类(或称单件类)。但在实际应用中,我们常常也需要使用半单例。下面我们具体谈谈单例和半单例,以及他们的用法和区别。

单例模式

单例模式(singleton)顾名思义,就是只有一个实例

作为对象的创建模式[GOF95]单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。

也就是说,对于一个单例类,不论实例化对象多少次,都只有一个对象实例,而且这个实例一定是一个全局的能被整个系统访问到。

下面是Objective-C中完整的单例类的实现:

Singleton.h


#import <Foundation/Foundation.h>


@interface Singleton : NSObject


+(id)shareInstance;


@end



Singleton.m



#import "Singleton.h"

static Singleton * instance = nil;

@implementation Singleton


+(id)shareInstance

{

   if(instance ==nil)

    {

        instance = [[super allocWithZone:nil]init]; //super调用allocWithZone            

    }

   return instance;

}


+(id)allocWithZone:(NSZone *)zone

{

   return [Singleton shareInstance];   

}


//可写可不写

- (id)init 

{

   if (instance) 

    {

       return instance;

    }

    

   self = [super init];

    return self;

}


-(id)copy

{

    return self;

}

- (id)copyWithZone:(NSZone *)zone

{

    return self;

}

-(id)retain

{

    return self;

}

- (onewayvoid)release 

{

    // Do nothing

}


- (id)autorelease 

{

    return self;

}


- (NSUInteger)retainCount 

{

   return NSUIntegerMax;

}

@end



解释说明:



1.static Singleton * instance = nil;

静态全局变量,始终指向实例化出的对象。


2.+(id)shareInstance;

外界初始化得到单例类对象的唯一借口,这个类方法返回的就是instance,即类的一个对象,

如果instance为空,则实例化一个对象,如果不为空,则直接返回。这样保证了实例的唯一。

3.-(id)copy;

- (id)copyWithZone:(NSZone *)zone;

这两个方法是为了防止外界拷贝造成多个实例,保证实例的唯一性。


4.-(id)retain;

因为只有一个实例对象,所以retain不能增加引用计数。


5.- (NSUInteger)retainCount;

因为只有一个实例对象,设置默认引用计数。这里是取的NSUinteger的最大值,当然也可以设置成1或其他值。


6.- (onewayvoid)release;

oneway void是用于多线程编程中,表示单向执行,不能回滚,即原子操作。


半单例

1.半单例不同于单例,它可以实例化多个对象。

2.在程序中系统要求能访问到这个类的当前对象实例。

比如说:我们对于一个ViewController,我们可以实例化多个。在ViewController中,我们给他添加了很多视图View

这些View中,当与用户发生某个交互时,我们由需要向Controller发送消息,实现响应操作。那么,View必须能找到当前的ViewController。这时,我们可以将ViewController设置成一个半单例类。


翻书程序为例:这里涉及到两个类LeavesViewControllerLeavesView

显然,我们是在LeavesViewController中添加多个LeavesView实现多页效果,

当判断出LeavesView翻到最后一页时,我们需要让LeavesViewController响应,跳到下一个Controller,其他场景视图。

LeavesViewController类为半单例

LeavesViewController.h


#import <UIKit/UIKit.h>

#import "LeavesView.h"


@interface LeavesViewController :UIViewController <LeavesViewDataSource,LeavesViewDelegate

{

LeavesView *leavesView;

}

@property(nonatomic,retain)LeavesView *leavesView;


+ (id)shareInstance;


- (void)goToPlay;

@end


LeavesViewController.m



#import "LeavesViewController.h"

#import "ASCcLevelOnePaperScene.h"


staticLeavesViewController *leavesViewInstance =nil;


@implementation LeavesViewController


@synthesize leavesView;

- (id)init 

{

   if (self = [superinit]) 

    {

        leavesView = [[LeavesViewalloc]initWithFrame:CGRectZero];

        leavesView.mode =UIInterfaceOrientationIsPortrait(self.interfaceOrientation) ? LeavesViewModeSinglePage :LeavesViewModeFacingPages;

       leavesViewInstance =self;       //注意这里

    }

    return self;

}


- (void)dealloc 

{

    [leavesView release];

   leavesViewInstance =nil;      //释放全局变量

    [superdealloc];

}


+ (id)shareInstance

{   

    //NSAssert(leavesViewInstance!=nil,@"leavesViewInstance can not be nil!");

    if(leavesViewInstance ==nil)

        leavesViewInstance = [selfinit];

    returnleavesViewInstance;

}


这里只展示了半单例的实现部分,关于Controller都有的ViewDidLoad等方法和其他相关实现方法,这里与半单例无关,不做展示


LeavesView只是一个普通的视图类。

LeavesView判断到最后一页时:


if([selfhasNextPage]==NO)

{

    NSLog(@"最后一页!");

    [[LeavesViewControllershareInstance]goToPlay];

}


[LeavesViewControllershareInstance]得到当前ViewController。再发送消息goToPlay,让ViewController响应。



0 0