iOS技术文章

OC:单例模式(Singleton)☀️

2016-06-24  本文已影响453人  LeaderBiao
  • 版权声明:本文为博主原创文章,未经博主允许不得转载。

单例模式的意思就是只有一个实例。单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。

1.单例模式的要点:

显然单例模式的要点有三个;一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。

2.单例模式的优点:

1.实例控制:Singleton 会阻止其他对象实例化其自己的 Singleton 对象的副本,从而确保所有对象都访问唯一实例。
  2.灵活性:因为类控制了实例化过程,所以类可以更加灵活修改实例化过程

iOS中的单例模式

1、为单例对象实现一个静态实例,并初始化,然后设置成nil,
  
2、实现一个实例构造方法检查上面声明的静态实例是否为nil,如果是则新建并返回一个本类的实例,
  
3、重写allocWithZone方法,用来保证其他人直接使用alloc和init试图获得一个新实力的时候不产生一个新实例,
  
4、适当实现allocWitheZone,copyWithZone,release和autorelease。

static MyClass *class = nil;  
  
@implementation MyClass  
  
+(MyClass *)sharedMyClass{  
    @synchronized(self){  //为了确保多线程情况下,仍然确保实体的唯一性  
        if (!class) {  
            [[self alloc] init]; //该方法会调用 allocWithZone  
        }  
    }  
    return class;  
}  
+(id)allocWithZone:(NSZone *)zone{  
    @synchronized(self){// //为了确保多线程情况下,仍然确保实体的唯一性  
        if (!class) {  
            class = [super allocWithZone:zone]; //确保使用同一块内存地址  
            return class;  
        }  
    }  
    return nil;  
}  
  
-(id)init  
{  
  if(class){  
     return class;  
  }  
  if(self = [super init]){  
   //进行一些初始化  
   }  
   return self ;  
}   
- (id)copyWithZone:(NSZone *)zone;{  
    return self; //确保copy对象也是唯一  
}  
  
-(id)retain{  
    return self; //确保计数唯一  
}  
  
- (unsigned)retainCount  
{  
   return UINT_MAX;  //装逼用的,这样打印出来的计数永远为-1  
}  
  
- (id)autorelease  
{  
    return self;//确保计数唯一  
}   
  
- (oneway void)release  
{  
     //重写计数释放方法 do nothing  
}  
@end  ```

 >再调试

MyClass *A = [[MyClass alloc] init];

NSLog(@"A:%@",A);

MyClass *B = [MyClass sharedMyClass];

NSLog(@"B:%@",B);

MyClass *C = [A copy];

NSLog(@"C:%@",C);```

打印出的是

A:<MyClass: 0x6a1e130>

B:<MyClass: 0x6a1e130>

C:<MyClass: 0x6a1e130>```

>都是指向同一块内存地址


- 然而这个人(<http://eschatologist.net/blog/?p=178>)觉的繁琐,所以给出如下实现:

@interface SomeManager : NSObject

/* 非线程安全的实现 */
@implementation SomeManager

/* 线程安全的实现 */
@implementation SomeManager

static id sharedManager = nil;

自苹果引入了Grand Central Dispatch (GCD)(Mac OS 10.6和iOS4.0)后,利用GCD(Grand Central Dispatch)ARC(Automatic Reference Counting)实现单例。

+(SchoolManager *)sharedInstance  
{  
    __strong static SchoolManager *sharedManager;  
      
    static dispatch_once_t onceToken;  
    dispatch_once(&onceToken, ^{  
        sharedManager = [[SchoolManager alloc] init];  
    });  
      
    return sharedManager;  
}  ```


>函数void dispatch_once( dispatch_once_t *predicate, dispatch_block_t block);其中第一个参数predicate,该参数是检查后面第二个参数所代表的代码块是否被调用的谓词,第二个参数则是在整个应用程序中只会被调用一次的代码块。dispach_once函数中的代码块只会被执行一次,而且还是线程安全的。

看到如下一篇文章,用宏实现(<https://gist.github.com/lukeredpath/1057420>):

//ExampleClass.m
@implementation MySharedThing

@end

GCDSingleton.h

define DEFINE_SHARED_INSTANCE_USING_BLOCK(block)

static dispatch_once_t pred = 0;
__strong static id _sharedObject = nil;
dispatch_once(&pred, ^{
_sharedObject = block();
});
return _sharedObject;

上一篇 下一篇

猜你喜欢

热点阅读