---------- IOS培训、java培训、期待与您交流! ----------
什么是单例模式 简单的说就是使得类的一个对象成为系统的唯一实例。用类来创建的每一个对象都是同一个实例。如果我们用%p来输出打印,我们会发现其内存地址是一样的。
或者说单例模式的意图是是的类的对象成为系统中唯一的实例,提供一个访问点,供客户类共享资源。
什么情况下使用单例?
1、类只能有一个实例,而且必须从一个为人熟知的访问点对其进行访问,比如工厂方法。
2、这个唯一的实例只能通过子类化进行扩展,而且扩展的对象不会破坏客户端代码。
单例设计模式的要点:
(1) 某个类只能有一个实例。
(2)他必须自行创建这个对象
(3)必须自行向整个系统提供这个实例;
(4)为了保证实例的唯一性,我们必须将
-(id)copyWithZone:(NSZone *)zone 、+(id)allocWithZone:(NSZone *)zone、 -(id)retain、 -(NSUInteger)retainCount
、-(oneway void)release -(id)autorelease 的实现方法进行覆盖。
(5)这个方法必须是一个静态类
一个经典的oc单例模式如下所示:
// static id sharedMyManager; //注意这里必须在类的.m文件中定义一个全局变量 // //sharedXXX defaultXXX currentXXX //默认的定义单例模式的命名方式 // // +(id)sharedMyManageer{ // if (sharedMyManager==nil) { //此处判断是确保实例的唯一性 // // sharedMyManager=[[self alloc]init]; // // } // return sharedMyManager; //第一次后每次通过这个类方法创建的对象都是唯一的实例 // } //
说到这里可能大家都了解的差不多了。下面我写了一个小例子来作为最经典简单的单例模式。 在arc模式下: 定义了一个dog类。
//// Dog.h// 笔记//// Created by micro on 15/3/2.// Copyright (c) 2015. All rights reserved.//#import <Foundation/Foundation.h>@interface Dog : NSObject@property (nonatomic ,assign) NSString * name;+(id)sharedMyDog;@end
//// Dog.m// 笔记//// Created by micro on 15/3/2.// Copyright (c) 2015. All rights reserved.//#import "Dog.h"static Dog *dog; //必须创建一个全局对象@implementation Dog+(id)sharedMyDog{ @synchronized(self){ //这段代码让线程进入atomic状态,如果多个线程进入这段代码,这段代码只能一个线程执行 if (dog == nil) { //第一次进入,存于全局变量中 dog=[[self alloc]init]; } } return dog; }- (instancetype)init{ self = [super init]; if (self) { self.name=@"wangwang"; } return self;}-(NSString *)description{ NSString * name = [NSString stringWithFormat:@"%@",self.name]; return name;}@end
在主函数中,我们对每个对象进行了地址的打印。,,并且打印出每个对象的dog name属性。
//// main.m// 笔记//// Created by micro on 15/3/2.// Copyright (c) 2015. All rights reserved.//#import <Foundation/Foundation.h>#import "Dog.h"int main(int argc, const char * argv[]) { @autoreleasepool { // insert code here... Dog * d1 =[Dog sharedMyDog]; Dog * d2= [Dog sharedMyDog]; NSLog(@"d1==%p,d2==%p",d1,d2); NSLog(@"d1的名字是%@,d2的名字是%@",d1,d2); Dog *d3=[Dog sharedMyDog]; d2.name=@"miaomiao"; NSLog(@"d1==%p,d2==%p,d3=%p",d1,d2,d3); NSLog(@"d1的名字是%@,d2的名字是%@,d3的名字是%@",d1,d2,d3); } return 0;}
运行结果如下:
2015-03-03 15:48:35.949单例笔记[1514:110062] d1==0x100406940,d2==0x100406940 2015-03-03 15:48:35.950单例笔记[1514:110062] d1的名字是wangwang,d2的名字是wangwang 2015-03-03 15:48:35.950单例笔记[1514:110062] d1==0x100406940,d2==0x100406940,d3=0x100406940 2015-03-03 15:48:35.951单例笔记[1514:110062] d1的名字是miaomiao,d2的名字是miaomiao,d3的名字是miaomiao Program ended with exit code: 0
在我们改改了d2对象的name属性的同时,d1,d3的name属性也随之改变。因为其内存地址是一样的。在此实现了单例模式。 注意我们在真正需要写或用单例时,千万不要像平时这样创建----Dog *dog=[[Dog alloc]init];
注意:所谓单例,即我们自己创建一个单例类,该类只能生成唯一的对象,即用 if (sharesingleton == nil) 方法来保证唯一性,为了防止该对象被复制(copy)或者retain 和 release 等操作,我们必须在所创建的单例的实现文件( .m 文件)中将父类的这些方法给覆盖,该目的是为了保证单例模式的一个严谨性。
|