单例模式,用于一个类始终只有一个实例,不管copy还是retain还是alloc等等,也不能被release,直到程序结束,都只有一个实例。
1.有的东西只能有一个,那就必须用单例;
2.单例的好处就是不会有多余的实例,所以节约内存;
3.因为只有一个单例,所以易于管理多线程对它的访问。
#import <Foundation/Foundation.h>
@interface User : NSObject<NSCopying> //拷贝协议表明该对象可被拷贝,尽管都是同一个(因为是单例)
@property(nonatomic,copy) NSString *name;
@property(nonatomic,copy) NSString *email;
+(id)shareUser; //一般用share或者default做前缀,易于阅读标记为单例共享方法
@end
#import "User.h"
static User *user1=nil; //先定义一个空得静态实例
@implementation User
+(id)shareUser{
@synchronized(self){ //线程锁,防止多线程访问冲突
if (user1==nil) { //判断这个实例是否为空,即是否已被创建
user1=[[[self class ]alloc]init]; //如果没被创建,就初始化一个
}
}
return user1; //如果已存在,则不创建,直接返回即可
}
//以下都是防止实例不是唯一的一些方法,是通用格式,不必死记硬背,可以直接拷贝到任何单例模式中
//这是在调用alloc时可防止重复创建实例
+(id)allocWithZone:(NSZone *)zone{
if (user1==nil) {
user1=[super allocWithZone:zone];
}
return user1;
}
//这是在拷贝对象时防止重复创建
-(id)copyWithZone:(NSZone *)zone{
return user1;
}
//这是在retain对象时防止重复创建,当然在ARC开启时可省略这个
-(id)retain{
return user1;
}
//在release时什么都不做,因为一共就一个实例,不重复引用,所以不能release
-(oneway void)release{ //除了返回单例,什么都不做
}
//在autorelease时,返回实例,在ARC下客省略
-(id)autorelease{
return user1;
}
//返回的时无符号整型,即大于0的数字,在ARC下可省略
-(NSUInteger)retainCount{ //替换掉引用计数——这样就永远都不会release这个单例?
return UINT_MAX;
}
@end
#import <Foundation/Foundation.h>
#import "User.h"
int main(int argc, const char * argv[]){
@autoreleasepool {
User *user1=[User shareUser];
User *user2=[User shareUser];
User *user3=[[User alloc]init];
User *user4=[user1 copy];
NSLog(@"%@,%@,%@,%@",user1,user2,user3,user4);
//四个对象是同一个,看地址可知,是同一个,即是单例
}
return 0;
}