欢迎关注我的iOS学习总结——每天学一点iOS:https://github.com/practiceqian/one-day-one-iOS-summary

一、iOS中事件传递和相应机制

  1. iOS中的事件(主要有三类)

    • 触摸事件(touch Event)
    • 运动/加速计事件(motion Event)
    • 远程控制事件(remote-control Event)
  2. UIResponder(响应者对象)

    • iOS中只有继承了UIResponder的类才能接收并处理事件,称之为响应者对象。

    • 为什么继承了UIResponder的类都能够接收并处理事件呢?

      • //UIResponder类提供了以下四个对象方法来处理触摸事件
        - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
        - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
        - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
        - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
        
  3. 事件响应链

    • 所有处理事件响应的类都是UIResponder的子类,响应者链是一个由不同对象组成的层次结构,其中的每个对象依次获得响应事件消息的机会,事件将沿着响应者链一直向下传递,直到该事件被接收并且处理

    • 事件的传递和响应链

      //事件传递是从第一响应者->UIApplication
      View->ViewController->UIWindow->UIApplication->nil
      //事件的响应是从UIApplication->FirstResponder
      UIApplication->UIwindow->ViewController->View
      
      • 可以通过[responder nextResponder]找到当前responder的下一个responder,持续这个过程,最后会找到UIApplication对象
      • 通常情况下,在first responder(即用户所点击的view)就会处理事件请求,进入事件分发机制
    • 几种继承关系

      • UIWindow->UIView->UIResponder
      • UIApplication->UIResponder
  4. 事件分发机制

    • 第一响应者指的是当前接受触摸的响应者对象(通常是一个UIView对象),表示当前对象正在与用户进行交互,它是响应链的开端,响应链和事件分发机制都是为了找出第一响应者
    • 当发生触摸操作后,系统会将该操作打包成一个UIEvent对象,并将其放入当前活动Application的事件队列(队列的特点是先进先出,先发生的事件先处理)
    • UIApplication会从事件队列中取出事件并将其分发给当前应用的UIWindow对象
    • UIwindow对象首先会使用hitTest:withEvent:方法寻找该触摸事件发生时所在的视图,histTest->view
    • hitTest:withEvent:方法的处理流程
      • 调用pointInside:withEvent:方法判断触摸点是否在当前视图内
      • 如果返回no,则hitTest方法返回nil,如果返回yes,则向当前视图的所有子视图发送hitTest:withEvent消息
      • 如果第一次有子视图返回非空对象,那么UIWindow对象调用的histTest:withEvent(UIWindow继承自UIView,UIView含有hitTest方法)方法返回该对象,如果所有的子视图都返回nil,那么histTest:withEvent方法返回自身
    • 如果histTest:withEvent方法没有找到第一响应者或者第一响应者没有处理该事件,那么该事件就会沿着响应者链向上回溯,如果UIWindow对象和UIApplication对象都不能处理该事件,那么该事件就会被丢弃。
    • 如果对事件响应需要有特殊的操作,那么可以重写hisTest:withEvent方法来实现
    • UIView(或者继承自UIView的子类)不能接收触摸事件的三种情况
      • UIView的userInteractionEnabled设置为NO(不可交互)
      • UIView的hidden设置为YES(隐藏了UIView,父控件隐藏的话子控件也会被隐藏)
      • alpha透明度<0.01(0~0.01)为透明
  5. UIApplication的几种状态

    • not Running(程序未启动状态)
    • Inactive(未激活)程序在前台运行,但是没有接收到事件,在没有事件需要处理的情况下程序通常处于这个状态
    • active(激活)程序在前台运行,并且接收到了事件
    • Background(后台),程序在后台运行并且可以执行代码,大多数程序挂起到后台都会在这个状态停留一会,一段时间后会进入挂起(Suspended)状态,经过特殊处理的请求可以长期处于这个状态。
    • Suspended(挂起),程序在后台运行但是不能执行代码,系统自动把程序变成这个状态并且不会发出通知,但是还在内存中运行,当系统遇到内存压力时,就会自动将程序从内存中清除,为前台程序提供更多的内存。

二、iOS中的设计模式

  1. 设计原则

    • 单一职责原则

      • 一个类只承担一个职责,如果一个类拥有了两种职责,那么需要考虑是否将这个类拆分开来,比如UITableViewCell,如果有多重样式的cell,那么我们应该考虑的是分成几种类型的cell去写,而不是在一个cell中实现多种类型
    • 开闭原则
      • 对软件实体的修改,最好使用扩展而非直接修改的方式
      • 对类,函数,如果需要修改,尽量采用继承的方式来扩展类的功能,而不是直接修改类的代码(如果工程不是特别复杂的情况下,那么直接修改类的代码也可以)
    • 里式替换原则
      • 子类可以扩展父类的方法,但不应该重写父类的方法
    • 接口隔离原则
      • 对象不应被强迫依赖它不使用的方法
    • 依赖倒置原则
      • 高层模块不应该依赖底层模块,二者都应该依赖其抽象,抽象不应该依赖细节,细节应该依赖抽象
    • 迪米特法则
      • 一个对象对另一个对象了解的越多,那么他们的耦合度就越高,当修改一个对象时,对另一个对象的影响就越大(一个对象应该对另一个对象保持最少的了解,尽量实现低耦合高内聚)
    • 组合/聚合复用原则
      • 尽量使用合成/聚合,在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分,新的对象通过对这些对象的委派达到复用已有功能的目的(尽量使用合成/聚合,不要使用继承)
  2. iOS开发中几种常用的设计模式

    • 单例模式(两种实现方法)

      • //使用@synchronized保证线程安全的懒加载写法,但是由于@synchronized是互斥锁导致性能比较低
        + (Singleton *)sharedInstance { @synchronized (self) {if (!instance) { instance = [[Singleton alloc] init];} }return instance;
        }
        //使用GCD中的dispatch_once写法,同时满足了线程安全和静态分析器的要求
        + (Singleton *)sharedInstance { static dispatch_once_t predicate;dispatch_once(&predicate, ^{instance = [[Singleton alloc] init];});return instance;
        }
        
      • 以上两种单例模式的实现都不能保证SingleTon是唯一的,因为通过[[Single alloc]init]方式创建仍然会创建出新的实例

      • 创建绝对单例的方法

        //通过拦截alloc方法来创建绝对单例
        //new->alloc
        //alloc->allocWithZone
        //alloc方法的内部就是调用了allocWithZone方法,allocWithZone方法的作用就是申请空间创建对象并将创建的对象返回。
        + (instancetype)shareInstance
        {if (instance == nil) {static dispatch_once_t once;dispatch_once(&once, ^{instance = [[Singleton alloc] init];});}return instance;
        }+ (instancetype)allocWithZone:(struct _NSZone *)zone
        {if (instance == nil) {static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{instance = [super allocWithZone:zone];});}return instance;
        }
        
    • 工厂模式

      • //一个工厂类需要执行多个方法,可以将每个方法衍生出一个类继承自这个工厂类,实例化工厂类时根据传入的参数创建对应方法的实例
        @implementation OperationFactory+ (Operation *) createOperat:(char)operate{Operation *oper = nil;switch (operate) {case '+':{oper = [[OperationAdd alloc] init];break;}case '-':{oper = [[OperationSub alloc] init];break;}case '*':{oper = [[OperationMul alloc] init];break;}case '/':{oper = [[OperationDiv alloc] init];break;}default:break;}return oper;
        }
        @end
        
    • 委托模式(这里只列出使用步骤,A为委托对象,B为代理对象)

      • 类A接口为文件中创建协议,声明@requeired和@optional方法

      • 类A添加一个属性,使用weak修饰(否则会造成循环引用)

        @property (nonatomic,wead) id<协议名>delegate

      • 类B接口文件/类扩展中遵守协议,并在实现文件中实现协议的required/optional方法

      • 类B中创建一个类A对象,类A对象的delegate设置为self(类B自身)

      • 在类A对象中调用[self.delegate 方法]

    • 观察者模式(两种方式)

      • 使用NSNotification通知实现
      • 使用KVO(key,value,observer)键值观测实现

iOS-事件响应链、单例模式、工厂模式、观察者模式相关推荐

  1. IOS中的事件响应链,事件冒泡机制基本了解

    本文主要讲解IOS中事件响应链,即事件冒泡机制.做过web开发的同学应该知道js事件冒泡是从主响应元素一层一层的向父级冒泡事件,在ios亦是如此,但是不同是ios中,如果冒泡链中有一方对事件进行响应处 ...

  2. 追踪app崩溃率、事件响应链、Run Loop、线程和进程、数据表的优化、动画库、Restful架构、SDWebImage的原理...

    1.如何追踪app崩溃率,如何解决线上闪退 当 iOS设备上的App应用闪退时,操作系统会生成一个crash日志,保存在设备上.crash日志上有很多有用的信息,比如每个正在执行线程的完整堆栈 跟踪信 ...

  3. 《JAVA与模式》26天系列—第12天—享元模式=单例模式+工厂模式+合成模式

    享元模式=单例模式+工厂模式+合成模式 单例模式: 保证一个类仅有一个实例,并提供一个访问它的全局访问点. 结构图: 注意多线程的单例. package com.bankht.Flyweight.co ...

  4. 单例模式 工厂模式 代理模式 适配器模式

    单例模式 概念: java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必 ...

  5. 基础设计模式:单例模式+工厂模式+注册树模式

    单例模式: 通过提供自身共享实例的访问,单例设计模式用于限制特定对象只能被创建一次. 使用场景: 一般数据库实例都会用单例模式 实现: 单例设计模式就是要一个类只能实例化一个对象. 要想让一个类只能实 ...

  6. 单例模式--工厂模式

    单例模式又称为职责模式,它用来在程序中创建一个单一功能的访问点,通俗地说就是实例化出来的对象是唯一的. 所有的单例模式至少拥有以下三种公共元素: 1. 它们必须拥有一个构造函数,并且必须被标记为pri ...

  7. iOS 21种设计模式之工厂模式

    原创Blog,转载请注明出处 http://blog.csdn.net/hello_hwc?viewmode=list 我的stackoverflow 感谢 感谢<Pro Objective-C ...

  8. 常见的设计模式(单例模式工厂模式)

    目录 一.为什么要学习设计模式? 二.单例模式 概念 优点 缺点 1.饿汉模式 1.1概念 1.2示例 2.懒汉模式 2.1 概念 2.2 示例 三.工厂模式 1.概念 2.使用场景 3.工厂方法 一 ...

  9. iOS事件传递链与响应链

    ✅作者简介:大家好我是瓜子三百克,励志成为全栈工程师的一枚程序猿,也是喜欢在学习和开发中记录笔记的小白博主!

  10. iOS:个人浅谈工厂模式

    一.什么是工厂方法? 正式的解释是:在基类中定义创建对象的一个接口,让子类决定实例化哪个类.工厂方法让一个类的实例化延迟到子类中进行.工厂方法要解决的问题是对象的创建时机,它提供了一种扩展的策略,很好 ...

最新文章

  1. Linux 启动流程即init程序分析--2
  2. Linux下ICMP洪水***实例
  3. 部分格式文件解释以及万能文件查看器下载
  4. 微信小程序中实现人脸识别认证
  5. 微信小程序地图添加标记点
  6. PhotoShop PS 教程 100例
  7. java 同比数据怎么算的_如何计算同比的计算公式?
  8. 一个独到程序员的深刻见解(转)
  9. macbook 虚拟机安装win7
  10. 关于 NM_CONTROLLED和Network Manager
  11. Vue-basic 19.单文件组件
  12. 京东客服岗位人才考试
  13. lsdyna如何设置set中的node_list_ANSA中进行二次开发的Python基础知识
  14. 白话电子签章原理及风险
  15. 古墓里出土的那些奇怪文物,能否证明穿越的存在?
  16. 【计算机网络】边缘路由器 三种家庭接入网(光纤到户) DSL、HFC与PON
  17. Yum工具详解(二)-----Yum配置阿里源
  18. PHP 脚本在服务器上执行
  19. SOA架构与微服务架构到底是什么?以及对应的一些常用的框架简介
  20. mysql 8.0 解决报错Public Key Retrieval is not allowed

热门文章

  1. 51单片机4位数码管按键显示
  2. Python 强制限定小数点位数
  3. Pandas合并表格的方法总结
  4. 推荐几个摸鱼时常看的技术网站
  5. L2、L3协议开发之以太网交换机基础
  6. Android API 中文(13) —— ToggleButton
  7. 做京东运营2年的感悟(转自派代网 乔先生)
  8. 内核驱动隐藏自身【断链】
  9. 关于递归删除链表结点时为什么不会出现断链问题
  10. 怎样利用腾讯云或者腾讯云主机搭建自己的网站