原文:http://www.jianshu.com/p/bf431fff235e

我们经常在编程中使用各种设计模式,在iOS中比较常见的设计模式有:单例模式、委托模式、观察者模式,当然实际上在Cocoa和Cocoa Touch框架中不仅仅是设计到这些设计模式,还有很多设计模式以及常规设计模式的变种等等。那什么是设计模式呢?

在软件工程中,设计模式(design pattern)是对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案。这个术语是由埃里希·伽玛(Erich Gamma)等人在1990年代从建筑设计领域引入到计算机科学的。(引自维基百科)

设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的;设计模式使代码编制真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。(引自百度百科)

通过解释我们可以基本了解设计模式是什么这个问题,当然我们不在这里深入探讨设计模式概念理论方面的问题,而是对我们在iOS开发中常用到的几种设计模式进行梳理,以方便日常开发。

Tips:设计模式和架构模式通常容易混淆

  1. 不同点 设计模式是解决某类常见问题的方法思路总结(尺度小) 框架模式是从软件开发总体结构上提出的一中框架结构(尺度大)
  2. 共同点 降低耦合度、调高可拓展性、易维护

比如:MVC是架构模式,单例是设计模式

1. 单例模式(Singleton)

什么是单例

在程序的整个生命周期内,保证类只有一个实例对象并可在全局调用。

如何实现单例

实现单例我们需要注意两点:1.我们需要保证单例被实例化一次之后,不能被重复实例化2.在多线程模式下避免同时被一个以上的线程调用实例化方法而造成多个实例。

实现单例:

@synchronized同步锁

static SingletonInstant *_single = nil;

@implementation SingletonInstant

+ (instancetype)sharedInstant {
if (!_single) { // 判断放在加锁之前防止多次加锁
@synchronized(self) { // 添加同步锁防止保证线程安全
_single = [[super allocWithZone:NULL] init];
}
}
return _single;
}
// 上面使用allocWithZone不使用alloc是因为alloc方法会调用
// allocWithZone方法,如果使用alloc还要在重载的allocWithZone中
// 在实现一次判断和加锁,因此为了简化代码,
// 直接使用allocWithZone,在重载的方法中只要调用一次单例方法就可以了
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
return [self sharedInstant];
}
// copy方法也会调用copyWithZone方法,因此直接返回self就好
- (id)copyWithZone:(NSZone *)zone {
return self;
} @end #pragma - mark MRC实现
static SingletonInstant *_single = nil; + (SingletonInstant*)sharedManager
{
if (_single == nil) {
@synchronized (self) {
_single = [[super allocWithZone:NULL] init];
}
}
return _single;
} + (id)allocWithZone:(NSZone *)zone
{
return [[self sharedManager] retain];
} - (id)copyWithZone:(NSZone *)zone
{
return self;
}
// 比ARC多出来的关于内存管理的几个方法
- (id)retain
{
return self;
} - (NSUInteger)retainCount
{
return NSUIntegerMax; //denotes an object that cannot be released
} - (void)release
{
//do nothing
} - (id)autorelease
{
return self;
}

更多关于alloc和allocWithZone的问题请查阅参考4,MRC实现查阅参考3

GCD加锁

使用 dispatch_once_t 保证线程安全

static SingletonInstant *_single = nil;

@implementation SingletonInstant

+ (instancetype)sharedInstant {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (!_single) {
_single = [[super allocWithZone:NULL] init];
}
});
return _single;
} + (instancetype)allocWithZone:(struct _NSZone *)zone {
return [self sharedInstant];
} - (id)copyWithZone:(NSZone *)zone {
return self;
} @end

在dispatch_once方法中的代码在程序的真个声明周期只会执行一次。,关于GCD请自行学习。

MRC不再详述

单例的实现基本雷同,在网上也有一些大同小异的其他写法,只要掌握单例思想,任何一种实现都是可以的,差异在细节上,孰优孰劣任君斟酌。

iOS Common Design Patterns:常用设计模式的更多相关文章

  1. Streamline Your App with Design Patterns 用设计模式精简你的应用程序

    Back to Design Patterns Streamline Your App with Design Patterns 用设计模式精简你的应用程序 In Objective-C progra ...

  2. 【design patterns】设计模式

    1.单例设计模式(singleton) 用途举例:对于多个程序使用同一个配置信息对象时比如在连接数据库时使用单例模式,每次只取出一个连接 步骤:①私有化该类的构造函数 ②私有化一个静态的对象 ③公有化 ...

  3. Head First Design Patterns HeadFirst 设计模式

    OO原则是我们的目标,而设计模式是我们的做法. 策略模式 (Strategy) 在软件开发上,一直不变的真理是"change".不管软件设计的多好,一段时间之后,总是要成长与改变, ...

  4. Java设计模式(Design Patterns)——可复用面向对象软件的基础

    设计模式(Design Patterns) 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结. 使用设计模式是为了可重用代码.让代码更容易被他 ...

  5. Apex Design Patterns

    Apex allows you to build just about any custom solution on the Force.com platform. But what are the ...

  6. TypeScript Version 23 Design Patterns

    TypeScript Version 23 Design Patterns TypeScript 设计模式 https://refactoring.guru/design-patterns/types ...

  7. Start Developing Mac Apps -- Design Patterns 设计模式

    Design Patterns A design pattern solves a common software engineering problem. Patterns are abstract ...

  8. Design Patterns Simplified - Part 3 (Simple Factory)【设计模式简述--第三部分(简单工厂)】

    原文链接:http://www.c-sharpcorner.com/UploadFile/19b1bd/design-patterns-simplified-part3-factory/ Design ...

  9. 设计模式(Design Patterns)

    设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...

随机推荐

  1. JS-常用方法合集

    部分方法使用jQuery!!!//tab切换 /* * 参数tablist为触发事件id * 参数tabmain为执行切换id * 参数ev为触发事件的动作 */ function tab(tabli ...

  2. 【原】docker-compose 管理docker的多容器配置

    docker-compose管理docker的多容器配置,实现docker的自动化. version: '3.4' x-defaults: &defaults restart: unless- ...

  3. HeroM2连击技能设置和DB完整数据

    连击技能设置: M2\选项\功能设置\技能魔法\通用技能\连击技能 魔法DB: 81;倚天辟地;0;55;5;10;10;5;6;6;99;15;5;15;10;15;15;60;; 300;万剑归宗 ...

  4. 企业面试问题收集-java基础

    Java基础部分 1.1   在登录时进行后台验证,后台获取到loginpass与数据库值对比一直? 1.2   Java中的方法覆盖(Overwrite)和方法重载(Overloading)是什么意 ...

  5. HTML去除多余空白区域的方法

    在head标记中添加html,body{height:100%;}即可. 实例如下 <head><style>html,body{height:90%;}</style& ...

  6. 解决:jenkins jnlp安装 provided port 40127 is not reachable

    解决方法: 开放linux 防火墙40127端口允许下载jnlp centos7 解决如下: [root@hostuser chrome]# firewall-cmd --zone=public -- ...

  7. ABC156 F - Modularness

    题目链接 题意还是比较清楚的,给你q个询问,对每组询问的模数和初始值不同,求满足条件\(a_j~\textrm{mod}~m_i < a_{j + 1}~\textrm{mod}~m_i,(0 ...

  8. 在C中测试函数运行时间

    #include <stdio.h> #include <time.h> #include <math.h> clock_t start, stop; //cloc ...

  9. CCF认证 2019-12-3

    分析 后面的数据,坐标分布太离散,不能用一个二位数组来模拟垃圾分布.因此,考虑用一个数组记录每个垃圾点的位置. 先根据x坐标.再根据y坐标进行排序. 再遍历数组中的每一处垃圾点,判断其是否能建回收站( ...

  10. L298N模块的使用(文末有惊喜)

    这个模块有两个供电口,标示着“12V输入”的是功率驱动电源输入,供电范围可以是7-46V, 一般12V供电就能满足我们大部分的DIY需求.标示着“5V输出可不接”的是逻辑供电, 当我们将“板载5V输出 ...