OC基础-单例设计模式
来源:互联网 发布:网络重置怎么弄 编辑:程序博客网 时间:2024/06/08 06:02
一、概念
单例的概念和JAVA中原理类似,就是在整个程序声明周期中,该对象始终只有一份保存在内存中。单例对象是全局变量,方便数据共享。
二、单例的经典写法
static id sharedMyManager; +(id)sharedThemeManager{ if(sharedMyManager == nil){ sharedMyManager = [[self alloc] init]; } return sharedMyManager; }需要有一个全局的类的对象,在单例方法中,第一次调用该方法时,实例化该对象,以后每一次调用都返回该对象。多个指针指向同一内存空间。
单例的方法命名规范:
shared/default/current+类名
三、经典单例模式的一个例子
#import <Foundation/Foundation.h>//主题管理器@interface ThemeManager : NSObject{ //主题名称 NSString * _name;}@property(nonatomic, retain)NSString * name;//单例方法+(id)sharedThemeManager;@end#import "ThemeManager.h"//声明一个全局的该类的对象static ThemeManager * manager;@implementation ThemeManager//实现setter和getter@synthesize name = _name;//实现单例的方法+(id)sharedThemeManager{ if(manager == nil){ //manager = [[self alloc] init]; //只有第一次调用该方法的时候,才会创建对象的实例,并将该对象保存为全局变量,之后每一次调用该方法,都返回这个全局变量。 manager = [[[self class] alloc] init]; } return manager;}-(id)init{ self = [super init]; if(self){ self.name = [NSString stringWithFormat:@"Default"]; //使用Default作为初始化的name,取代nil } return self;}-(NSString *)description{ return [NSString stringWithFormat:@"Theme name is %@", self.name];}-(void)dealloc{ [_name release]; _name = nil; [super dealloc];}@end#import <Foundation/Foundation.h>#import "ThemeManager.h"int main(int argc, const char * argv[]) { @autoreleasepool { //使用单例创建两个对象,这里虽然使用alloc也没问题,但不建议这么做。既然是单例模式,就按照单例的规范来写 ThemeManager * tm1 = [ThemeManager sharedThemeManager]; ThemeManager * tm2 = [ThemeManager sharedThemeManager]; tm2.name = @"夏日倾情"; //使用%p输出对象的内存地址,结果是相同的,也就是两个对象指向同一内存空间。 NSLog(@"tm1 is %p, tm2 is %p", tm1, tm2); //这里由于默认的name是nil,我们可以重写init来修改这个值 NSLog(@"tm1:%@,tm2:%@", tm1, tm2); } return 0;}
四、单例模式的其他写法
1.经典单例模式的缺陷
经典单例模式,是工业级写法,但是有一个缺陷。如果有两个线程,同时调用了该单例方法,就有可能同时满足if(manager == nil)条件,创建了2个对象,造成内存泄露,是 非线程安全的。
2.加锁写法
类似java中的加锁写法
static ThemeManager * manager;+(id)sharedThemeManager{ //加锁,锁为self @synchronized(self) { if(manager == nil){ manager = [[self alloc] init]; } } return manager;}3.免锁写法
//免锁写法,Lock Free//该方法只在类的对象第一次alloc的时候调用,有且只调用一次。+ (void)initialize{ static BOOL initialized = NO; if (initialized == NO) { initialized = YES; manager = [[self alloc] init]; }}4.GCD写法
+(id)sharedThemeManager{ static dispatch_once_t once; dispatch_once(&once, ^{ manager = [[self alloc] init]; }); return manager;}
该写法,保证了即使有多个线程,{}代码块也只执行一次。
最常用的写法:经典写法、加锁写法、GCD写法
@诗未冷学习博客
0 0
- OC基础-单例设计模式
- OC 单例设计模式
- oc单例设计模式
- OC中的设计模式-单例模式
- OC视频笔记-单例设计模式
- OC循环渐进:单例设计模式
- OC 单例设计
- OC 单例模式
- OC单例模式
- oc 单例模式
- OC-单例模式
- OC - 单例模式
- OC-单例模式
- oc单例模式
- oc单例模式
- OC单例模式
- OC-单例模式
- Java基础-设计模式-单例模式
- 我的第一天博客!
- UITextView添加背景图片
- Laurenty and Shop(前序和,后序和的应用)
- Winsocket UDP Client and Server Examples
- Sqlite 数据库恢复工具
- OC基础-单例设计模式
- jw player,播mp4很好用,播swf功能不全!!!
- go学习笔记
- IO流的使用(一)
- 敏捷看板的递进
- C++STL之multimap多重映照容器
- 贡献30本经典Linux学习和开发教程和资料,都是pdf完整版的
- [自我解剖]别把时间浪费在工具上
- 【C/C++学习笔记】结构体的位域操作小结