Objective

来源:互联网 发布:淘宝店铺权重有哪些 编辑:程序博客网 时间:2024/06/08 09:54
1.什么是设计模式? 

在计算机编程语言中有32种设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。毫无疑问,设计模式于己于他人于系统都是多赢的;设计模式使代码编制真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样,在iOS中常用的实际模式为:代理方法,MVC模式,MVVC模式,单例模式等。


什么是单例设计模式?

单例顾名思义就是说一个类的实例只能有一个,在Java、C++这类语言中,可以通过将构造函数私有化来避免对象的重复创建,

但是Objective-C却不能够这样做,我们需要通过其他机制来达到这个目的。


我们知道,创建对象的步骤分为申请内存(alloc)、初始化(init)这两个步骤,我们要确保对象的唯一性,

因此在第一步这个阶段我们就要拦截它。当我们调用alloc方法时,oc内部会调用allocWithZone这个方法来申请内存,我们覆写这个方法,

然后在这个方法中调用shareInstance方法返回单例对象,这样就可以达到我们的目的。

拷贝对象也是同样的原理,覆写copyWithZone方法,然后在这个方法中调用shareInstance方法返回单例对象


代码如下:

#import <Foundation/Foundation.h>@interface Tools : NSObject// 一般情况下创建一个单例对象都有一个与之对应的类方法// 一般情况下用于创建单例对象的方法名称都以share开头, 或者以default开头+ (instancetype)shareInstance;@end#import "Tools.h"@implementation Tools+ (instancetype)shareInstance{    Tools *instance = [[self alloc] init];    return instance;}// 创建一个空对象static Tools * _instance = nil;+ (instancetype)allocWithZone:(struct _NSZone *)zone{    //    // 当前代码在多线程中可能会出现问题(多线程并发问题.出现多个线程同时创建对象,线程不安全)//    NSLog(@"%s",__func__);//    // 由于所有的创建方法都会调用该方法, 所以只需要在该方法中控制当前对象只创建一次即可//    if (_instance == nil) {//        NSLog(@"创建了一个对象");//        _instance = [[super allocWithZone:zone] init];//        //    }//    return _instance;        // 线程安全的单例写法            static dispatch_once_t onceToken;        dispatch_once(&onceToken, ^{            _instance = [[super allocWithZone:zone] init];        });        return _instance;    }// MRC- (oneway void)release{    // 为了保证程序过程中只有一份实例,这个方法什么都不做.}- (instancetype)retain{    return _instance;}- (NSUInteger)retainCount{//    return 1;    // 注意: 为了方便程序员之间沟通,一般情况下不会再单例中返回retainCount = 1;    // 而是返回一个比较大的值    return MAXFLOAT;}@end

效果如下:

main:#import <Foundation/Foundation.h>#import "Tools.h"int main(int argc, const char * argv[]) {        // 单例就是无论怎么创建都只能有一个实例对象    // 如果地址相同就代表着是同一个实例对象        Tools *t1 = [[Tools alloc] init]; //内部会调用 allocWithZone    Tools *t2 = [Tools new];          // [[alloc] init]  allocWithZone    Tools *t3 = [Tools shareInstance];    NSLog(@"t1 = %p",t1);    NSLog(@"t2 = %p",t2);    NSLog(@"t3 = %p",t3);        //    Tools *t2 = [[Tools alloc] init];//    [t2 retain];//    [t2 retain];//    [t2 retain];//    [t2 retain];//    NSLog(@"retainCount = %lu",[t2 retainCount]);//    NSLog(@"t2 = %p",t2);//    [t2 release];//    //    Tools *t1 = [Tools shareInstance];//    NSLog(@"t1 = %p",t1);//    [t1 release];        return 0;}

输出结果:

ARC输出结果:

2017-07-30 23:09:29.707705+0800 单例ARC写法和MRC写法[5474:213457] t1 = 0x1002026902017-07-30 23:09:29.707915+0800 单例ARC写法和MRC写法[5474:213457] t2 = 0x1002026902017-07-30 23:09:29.707931+0800 单例ARC写法和MRC写法[5474:213457] t3 = 0x100202690


MRC输出结果:(上方main方法中,注释的代码打开)

2017-07-30 23:10:11.185137+0800 单例ARC写法和MRC写法[5498:213824] retainCount = 42981267522017-07-30 23:10:11.185336+0800 单例ARC写法和MRC写法[5498:213824] t2 = 0x1003035a02017-07-30 23:10:11.185364+0800 单例ARC写法和MRC写法[5498:213824] t1 = 0x1003035a0

注意:这里我解释一下.在Tools的.m方法中.如果是ARC的情况.不必要重写release,retain,retainCount方法.

如果是MRC,要想实现单例,必须重写这个三个方法.


从输出结果上来,对象的地址都是一样的,说明是同一块存储空间.这样就只创建了一个对象.



原创粉丝点击