`
MagicBird
  • 浏览: 137425 次
  • 性别: Icon_minigender_2
  • 来自: 惠州
社区版块
存档分类
最新评论

Day7 oc 单例模式

    博客分类:
  • ios
 
阅读更多

OC单例模式

单例模式是ios里面经常使用的模式,例如[UIApplicationsharedApplication] (获取当前应用程序对象)、[UIDevicecurrentDevice](获取当前设备对象),单例模式的写法也很多。

 

实现单例模式有三个条件(摘自http://blog.csdn.net/jiangwei0910410003/article/details/41928053)

针对于这三个条件在OC中

1、类的构造方法是私有的

我们只需要重写allocWithZone方法,让初始化操作只执行一次

2、类提供一个类方法产生对象

这个可以直接定义一个类方法

3、类中有一个私有的自己对象

我们可以在.m文件中定义一个属性即可

第一种:非线程安全,也是最简单的实现

Singleton.h中,在.h文件中提供了一个类方法,用于产生对象

 

#import <Foundation/Foundation.h>

//设计单利类的目的,限制这个类只能创建一个对象
//构造方法为私有的
//保存一个全局的static变量
@interface Singleton : NSObject
+ (Singleton *)shareInstance;
@end

 Singleton.m

 

 

#import "Singleton.h"
//定义了一个static类型的对象
static Singleton * singleton = nil;//不能让外部访问,同时放在静态块中的

@implementation singleton
//提供一个获取单实例的类方法
+ (Singleton *)shareInstance{
    if(!singleton){
        // 这里调用alloc方法会进入下面的allocWithZone方法
        singleton = [[self alloc] init];
    }
    return singleton;
}
// 这里重写allocWithZone主要防止[[AdressBook alloc] init]这种方式调用多次会返回多个对象  
+ (id) allocWithZone:(NSZone *)zone{
    if(!singleton){
        singleton = [super allocWithZone:zone];
        return singleton;
    }
    return nil;
}
//其他方法也是需要重写的
//拷贝方法
- (id)copyWithZone:(NSZone *)zone{
    return singleton;;
}

//需要重写retain方法,不能让其引用+1
- (id)retain{
    return self;
}

//需要重写release方法,不能让其引用-1
- (oneway void)release{
    //do Nothing...
}
- (unsigned)retainCount  {  
    return UINT_MAX;  //denotes an object that cannot be released 
} 
- (id)autorelease{
    return self;
}

@end

 

 

main.m

 

#import <Foundation/Foundation.h>

#import "Singleton.h"
//单利模式
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        Singleton * singleton1 = [Singleton shareInstance];
        Singleton * singleton2 = [Singleton shareInstance];
        
        NSLog(@"%@", singleton1);//两个指针指向的是同一个对象
        NSLog(@"%@", singleton2);
        
    }
    return 0;
}

 

 

第二种:苹果提供过objective c单例的比较官方的写法(加入线程安全,防止多线程情况下创建多个实例 )

 

static Singleton *sharedSingletonManager = nil;
 
+ (Singleton*)sharedManager
{
    //加入线程安全,防止多个线程创建多个实例
    @synchronized(self) {
        if (sharedSingletonManager == nil) {
            [[self alloc] init]; // assignment not done here
        }
    }
    return sharedSingletonManager;
}
 
+ (id)allocWithZone:(NSZone *)zone
{
    @synchronized(self) {
        if (sharedSingletonManager == nil) {
            sharedSingletonManager = [super allocWithZone:zone];
            return sharedSingletonManager;  // assignment and return on first allocation
        }
    }
    return nil; //on subsequent allocation attempts return nil
}
 
- (id)copyWithZone:(NSZone *)zone
{
    return self;
}
 
- (id)retain
{
    return self;
}
 
- (unsigned)retainCount
{
    return UINT_MAX;  //denotes an object that cannot be released
}
 
- (void)release
{
    //do nothing
}
 
- (id)autorelease
{
    return self;
}

 

 第三种:iOS5之后普遍使用了ARC技术,原来这个写法就显得累赘,release已经不使用了。可以结合GCD来实现单例模式

ARC

ARC是iOS 5推出的新功能,全称叫 ARC(Automatic Reference Counting)。

简单地说,就是代码中自动加入了retain/release,原先需要手动添加的用来处理内存管理的引用计数的代码可以自动地由编译器完成了。使用的时候,就是通过指定的语法,让编译器(LLVM 3.0)在编译代码时,自动生成实例的引用计数管理部分代码。ARC并不是GC,它只是一种代码静态分析(Static Analyzer)工具。

GCD
GCD 是 libdispatch 的市场名称,而 libdispatch 作为 Apple 的一个库,为并发代码在多核硬件(跑 iOS 或 OS X )上执行提供有力支持。它具有以下优点:
1.GCD 能通过推迟昂贵计算任务并在后台运行它们来改善你的应用的响应性能。
2.GCD 提供一个易于使用的并发模型而不仅仅只是锁和线程,以帮助我们避开并发陷阱。
3.GCD 具有在常见模式(例如单例)上用更高性能的原语优化你的代码的潜在能力。
+ (Singleton*) sharedManager
{
  static Singleton *sharedSingletonManager = nil;
  static dispatch_once_t pred;
  dispatch_once(&pred, ^{
    sharedSingletonManager = [[self alloc] init]; // or some other init method
  });
  return sharedSingletonManager;
}
 通过上面的代码我们能够看出其实在ARC下单例的实现方式与非ARC下大同小异,只不过是没有重载内存管理的函数而已。而这也得益于ARC这种技术。

第四种单例工厂

        (摘自http://blog.jobbole.com/56439/)

在实际的编程工作中,随着项目规模的不断扩大,我们往往发现在整个项目中存在着大量的单例。于是我们就会遇到一个问题如何去管理这些单例。 同时,也要防止大量的重复代码。那么要管理这些单例,我们很自然的想到了工厂模式。

详细实现参见https://github.com/yishuiliunian/DZSinglonFactory.git

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics