当前位置:编程学习 > wap >>

IOS、Objective-C中单例类与半单例类

  在设计模式中有一个“单例模式”,对应的我们常常会设计“单例类”(或称单件类)。但在实际应用中,我们常常也需要使用“半单例”。下面我们具体谈谈单例和半单例,以及他们的用法和区别。
单例模式
单例模式(singleton)顾名思义,就是只有一个实例。
作为对象的创建模式[GOF95], 单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。
也就是说,对于一个单例类,不论实例化对象多少次,都只有一个对象实例,而且这个实例一定是一个全局的能被整个系统访问到。
下面是Objective-C中完整的单例类的实现:
Singleton.h
#import <Foundation/Foundation.h>
 
@inte易做图ce 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;
}
- (oneway void)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设置成一个半单例类。
 
以“翻书”程序为例:这里涉及到两个类LeavesViewController 和LeavesView
显然,我们是在LeavesViewController中添加多个LeavesView实现多页效果,
当判断出LeavesView翻到最后一页时,我们需要让LeavesViewController响应,跳到下一个Controller,其他场景视图。
LeavesViewController类为“半单例”:
LeavesViewController.h
#import <UIKit/UIKit.h>
#import "LeavesView.h"
 
@inte易做图ce LeavesViewController : UIViewController <LeavesViewDataSource, LeavesViewDelegate> 
{
LeavesView *leavesView;
}
@property(nonatomic,retain)LeavesView *leavesView;
 
+ (id)shareInstance;
 
- (void)goToPlay;
@end
 
LeavesViewController.m
#import "LeavesViewController.h"
#import "ASCcLevelOnePaperScene.h"
 
static LeavesViewController *leavesViewInstance = nil;
 
@implementation LeavesViewController
 
@synthesize leavesView;
- (id)init 
{
    if (self = [super init]) 
    {
        leavesView = [[LeavesView alloc] initWithFrame:CGRectZero];
        leavesView.mode = UIInte易做图ceOrientationIsPortrait(self.inte易做图ceOrientation) ? LeavesViewModeSinglePage : LeavesViewModeFacingPages;
        leavesViewInstance = self;       //注意这里
    }
    return self;
}
 
- (void)dealloc 
{
    [leavesView release];
    leavesViewInstance = nil;      //释放全局变量
    [super dealloc];
}
 
+ (id)shareInstance
{   
    //NSAssert(leavesViewInstance!=nil,@"leavesViewInstance can not be nil!");
    if(leavesViewInstance == nil)
        leavesViewInstance = [self init];
    return leavesViewInstance;
}
 
这里只展示了“半单例”的实现部分,关于Controller都有的ViewDidLoad等方法和其他相关实现方法,这里与“半单例”无关,不做展示
LeavesView只是一个普通的视图类。
当LeavesView判断到最后一页时:
if([self hasNextPage]==NO)
{
    NSLog(@"最后一页!");
    [[LeavesViewController shareInstance] goToPlay];
}
 
[LeavesViewControllershareInstance]得到当前ViewController。再发送消息goToPlay,让ViewController响应。
 
补充:移动开发 , IOS ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,