设计模式

设计模式

设计模式分为三种类型,共23种:

  1. 创建型模式: 单例、抽象工厂、建造者、工厂、原型
  2. 结构型模式:适配器、桥接、装饰、组合、外观、享元、代理
  3. 行为型模式: 模板方法、命令、迭代器、观察者、中介、备忘录、解释器、状态、策略、职责链、访问者模式。

MVC

Model-View-Controller,以Model作为数据工厂,放入数据对象。Controller作为桥梁,处理业务,而View只是数据展示层,理论上应该与业务无关,MVC降低了耦合性,提供了重用性和适用性,可有效的提高哦开发效率。

MVVM把原来在Controller的业务逻辑、网络请求、数据存储等操作和表现逻辑,分离到ViewModel中,从而使ViewController得到精简。

MVC中,Controller同时控制Model和View,MVVM中,ViewModel作为一个过渡,Model的数据获取和加工由ViewModel负责,得到合适View的数据,利用绑定机制,使得View得以自动更新。

单例模式

单例模式:它可以保证某个类创建出来的对象永远只有1个。类的一个对象成为系统中的唯一实例。一个类仅有一个实例,并提供一个访问它的全局访问点。
定义包含三个要点:一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须向整个系统提供这个实例。

何时使用单例

  1. 类只能有一个实例。作用:节省内存资源
  2. 这个唯一的实例只能通过子类化进行扩展,而且扩展的对象不会破坏客户端代码。

单例模式的实现

在Objective-C中实现单例模式,需要完成如下四个步骤:

第一步:定义一个静态实例变量mySingleton(名字可以自己取),初始化为nil,代码如下所示:

static MySingleton *mySingleton = nil;

第二步:实现一个类方法检查上面声明的静态实例是否为nil,如果是则新建并返回一个本类的实例,代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
+ (id)sharedInstance
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if(mySingleton == nil)
{
mySingleton = [[self alloc] init];
// mySingleton = [[super allocWithZone:NULL]init]; 如果在self中重载了基本的对象分配方法,就需要借用父类(NSObject)的功能,来帮助处理底层内存分配的杂务
}
});
return mySingleton;
}

dispatch_once函数是GCD中的API,它保证应用程序即使在多线程环境下,也只执行一次。当然,也可以使用@synchronize来达到线程安全的目的,如下:

1
2
3
4
5
6
7
8
9
10
11
+ (id)sharedInstance
{
@synchronized (self)
{
if (mySingleton == nil)
{
mySingleton = [[self alloc] init];
}
}
return mySingleton;
}

第三步:重写allocWithZone方法,用来保证使用alloc和init试图获得一个新实例的时候不产生新实例,代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
+ (id)allocWithZone:(NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (mySingleton == nil)
{
mySingleton = [super allocWithZone:zone];
NSLog(@"allocWithZone");
}
});
return mySingleton;
}

第四步:适当实现copyWithZone,release和autorelease等方法。代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// 如果有其他初始化操作,可在这里进行初始化
- (id)init
{
self = [super init];
if (self != nil)
{
// 其他初始化操作
}
return self;
}

// 防止外界拷贝造成多个实例,保证实例的唯一性。
- (id)copyWithZone:(NSZone *)zone
{
return self;
}

// 因为只有一个实例对象,所以retain不能增加引用计数。
- (id)retain
{
return self;
}

// 因为只有一个实例对象,设置默认引用计数。这里是取的NSUinteger的最大值,当然也可以设置成1或其他值。
- (NSUInteger)retainCount
{
return UINT_MAX; // denotes an object that cannot be released
}

// oneway是用于多线程编程中,表示单向执行,不能“回滚”,即原子操作。该方法是空的,不让用户release掉这个对象。
- (oneway void)release
{
//do nothing
}

//除了返回单例外,什么也不做。
- (id)autorelease
{
return self;
}

// 该方法永远不会被调用,因为在程序的生命周期内容,该单例一直都存在。(所以该方法可以不实现)
- (void)dealloc
{
[super dealloc];
}

子类化Singleton

【补充】说明,对于第二步和第三步可以这样实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
+ (id)sharedInstance
{
@synchronized(self)
{
if(mySingleton == nil)
{
mySingleton = [[super allocWithZone:NULL] init];
NSLog(@"allocWithZone");
}
}
return mySingleton;
}

// 通过返回当前的sharedInstance实例,就能防止实例化一个新的对象。
+ (id)allocWithZone:(NSZone *)zone
{
return [[self sharedInstance] retain];
}

alloc调用被转发给super,意味着NSObject晖处理对象分配,如果不做修改的子类化Singleton,返回的实例总是Single。因为Singleton重载了所以实例化相关的方法,实现如下:

1
2
3
4
5
6
7
8
9
10
11
@implementation SingletonSon
static Singleton *shareSingleton=nil; //向上转型,重定义自己的sharedsingleton类变量,不与父类共享。
+(SingletonSon *) shareInstance
{
if(sharedSingleton==nil)
{
//不调用父类alloc方法,在此调用父类alloc方法可能回调此方法,从而产生死循环,我们直接创建对象。(重点下面函数)
sharedSingleton=[NSAllocateObject(self class),0,NULL) init];
}
}// 子类可以重写一下retain copy release autorelease进行合适的内存管理。
@end
  1. 单例模式实现代码:(MRC)
    static MJSoundTool *_soundTool = nil;

    若是ARC:
    在build加标记-fobjc-arc
    与MRC类似,只是没有了release,retain。
    在宏中用if__has_feature(objc_arc)判断
    创建单例设计模式的基本步骤:
    • 声明一个单件对象的静态实例,并初始化为nil。
    • 创建一个类的类工厂方法,当且仅当这个类的实例为nil时生成一个该类的实例
    • 实现NScopying协议, 覆盖allocWithZone:方法,确保用户在直接分配和初始化对象时,不会产 生另一个对象。
      @interface MJSoundTool : NSObject<NSCopying>
    • 覆盖release、autorelease、retain、retainCount方法, 以此确保单例的状态。
    • 在多线程的环境中,注意使用@synchronized关键字或GCD,确保静态实例被正确的创建和初始化。

单例模式在IOS中的应用

单例模式在IOS中的应用非常广泛,如 UIApplication、NSUserDefault
  [NSNotificationCenter defaultCenter]、
  [UIApplication sharedApplication]、
  [NSFileManager defaultManager]
  [UIAccelerometer sharedAccelerometer]接收来自单例实例的加速度数据等。
用在登录界面和一些第三方框架的二次封装等

观察者

KVO和NSNotification。KVO是被观察者主动向观察者发送消息。NOtification是被观察者想NotificationCenter发送消息,再由NotificationCenter post通知到每个注册的观察者。

代理

通知

KVC。KVO

工厂模式

自定义VIew用到。

  

文章目录
  1. 1. MVC
  2. 2. 单例模式
    1. 2.1. 何时使用单例
    2. 2.2. 单例模式的实现
    3. 2.3. 子类化Singleton
    4. 2.4. 单例模式在IOS中的应用
  3. 3. 观察者
  4. 4. 代理
  5. 5. 通知
  6. 6. 工厂模式
本站总访问量 本站访客数人次 ,