单例设计在设计模式中是一种比较重要的模式,当用户只想要生成一个实例化对象的时候,就可以把该类设计成单例模式。
单例模式一般应用于内存开销比较大的来,在OC中被设计成单例的常见系统类有:NSNotificationCenter(通知中心),NSFileManager(文件管理)......
NSNotificationCenter 实例化对象代码如下:
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
NSFileManager 实例化对象代码如下:
NSFileManager *fm = [NSFileManager defaultManager];
根据OC官方类的命名规范,当我们自定义一个单例类时,遍历构造器(就是生成单例对象的类方法)一般命名为default+类名称,这叫‘见文知义’;
当然,你也可以命名为:share+类名称,或者:shareInstance,defaultInstance
我们一般会遵循上面的命名规则,而不会去取一些乱七八糟的名字。
在MRC环境下建立Student单例类代码实现如下:
Student.h文件代码如下:
#import <Foundation/Foundation.h>
@interface Student : NSObject <NSCopying>
+ (Student *)defaultStudent;
//或者:shareStudent/defaultStudent/defaultInstance/shareInstance
//个人规定:个人创建的叫defaultInstance/系统默认的为defaultXxxxx;
@end
Student.m的文件代码如下:
#import "Student.h"
static Student *student = nil;
@implementation Student
//因为student为静态变量,生命周期和程序的生命周期一样,所有不需要做内存管理
+ (Student *)defaultStudent {
if (!student) {
student = [[Student alloc] init];
}
return student;
}
//为了防止通过alloc或new创建新的实例
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
@synchronized(self) {
if (student == nil) {
student = [super allocWithZone:zone];
}
return student;
}
}
//为了防止copy产生新的对象
- (id)copyWithZone:(NSZone *)zone {
return self;
}
//以下四个方法在ARC环境下不用重写
//防止引用计数加一
- (instancetype)retain {
return self;
}
//不应许返回单例对象的引用计数
- (NSUInteger)retainCount {
return NSUIntegerMax;
}
//防止引用计数减一
- (oneway void)release {
}
//防止自动释放
- (instancetype)autorelease {
return self;
}
@end
main.h的代码如下:
#import <Foundation/Foundation.h>
#import "Student.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Student *stu1 = [Student defaultStudent];
NSLog(@"%p",stu1);
Student *stu2 = [[Student alloc] init];
NSLog(@"%p",stu2);
}
return 0;
}
测试结果如下:
2015-08-07 19:52:29.415 Demo22[38491:281697] 0x10030a430
2015-08-07 19:52:29.417 Demo22[38491:281697] 0x10030a430
实例化的两个对象指内存地址一样,单例类构造成功!