基本概念
始终返回一个实例,即一个类始终只有一个实例
创建单例设计模式的基本步骤
声明一个单件对象的静态实例,并初始化为nil
创建一个类的类方法,生成一个该类的实例,当且仅当这个类的实例为nil时
覆盖allocWithZone:方法,确保在直接分配和初始化对象时,不会产生另一个对象
实现NSCopying协议,覆盖retain,reatinCount方法,以此确保单例的状态(非ARC,还要覆盖release和autorelease)
在多线程的环境中,注意使用@synchronized关键字,确保静态实例被正确的创建和初始化
实例代码:
User.h
#import <Foundation/Foundation.h> @interface UserContext : NSObject<NSCopying> @property(nonatomic,copy)NSString *userName; +(id)shareUserContext; @end
User.m
#import "UserContext.h" static UserContext *Instance = nil;//定义一个静态实例,并初始化为nil
@implementation UserContext +(id)shareUserContext{ @synchronized(self){//线程保护 if (Instance == nil) { Instance = [[[self class] alloc] init]; } } return Instance; } #pragma mark - 以下的方法是为了确保只有一个实例对象 +(id)allocWithZone:(struct _NSZone *)zone{ if (Instance == nil) { Instance = [super allocWithZone:zone]; } return Instance; } //实现Copy协议,返回实例 -(id)copyWithZone:(NSZone *)zone{ return Instance; } /* 非ARC下,还需覆盖下面这些方法 //返回实例 -(id)retain{ return Instance; } //什么都不做 -(oneway void)release{ } //返回实例 -(id)autorelease{ return Instance; } //返回一个无符号整型范围最大值 -(NSUInteger)retainCount{ return UINT_MAX; } */ @end
main.m
#import <Foundation/Foundation.h> #import "UserContext.h" int main(int argc, const char * argv[]) { @autoreleasepool { // insert code here... NSLog(@"Hello, World!"); UserContext *user = [UserContext shareUserContext]; UserContext *user2 = [[UserContext alloc] init]; UserContext *user3 = [user copy]; user.userName = @"桐人"; NSLog(@"user:%@",user.userName); NSLog(@"user2:%@",user2.userName); NSLog(@"user3:%@",user3.userName); NSLog(@"");//在这里加入断点,可查看内存地址 } return 0; }
运行结果:
2014-01-04 11:25:34.611 单例[1427:303] Hello, World! 2014-01-04 11:25:34.612 单例[1427:303] user:桐人 2014-01-04 11:25:34.612 单例[1427:303] user2:桐人 2014-01-04 11:25:34.613 单例[1427:303] user3:桐人 (lldb)
内存地址:
user2 UserContext * 0x100700190 0x0000000100700190 user3 UserContext * 0x100700190 0x0000000100700190 user UserContext * 0x100700190 0x00000001007