黑马程序员技术交流社区
标题: oc中的单例模式 [打印本页]
作者: Micro 时间: 2015-3-4 22:02
标题: oc中的单例模式
---------- 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 文件)中将父类的这些方法给覆盖,该目的是为了保证单例模式的一个严谨性。
作者: Micro 时间: 2015-3-4 22:05
由于显示的原因。。。欢迎到我的博客去看:::http://blog.csdn.net/oflyme12
作者: itheima2xy 时间: 2015-3-5 09:46
写得很好,给你点个赞!!{:2_30:}
作者: keeganlee 时间: 2015-3-5 09:49
顶起来
作者: manitowang 时间: 2015-3-10 22:07
赞一个!
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |