该了解的iOS(二)之核心

该了解的iOS(二)之核心

iOS的核心篇章我主要说深入理解设计模式、组件化,模块化,插件化和app运行时的质量监控等知识点,不是说别的篇章不是核心篇章,如优化,静、动态分析等,我会有专门的篇章来详解它们,不能使一篇文章读下来找不到重点。

深入理解设计模式

设计模式中有六大基本原则,它们是设计模式的核心指导思想,分别为:

  • 单一职责原则(single responsibility principle):实现类要职责单一
  • 里氏替换原则(liskov substitution principle):不要破坏继承体系
  • 依赖倒置原则(dependence inversion principle):面向接口编程
  • 接口隔离原则(interface segregation principle):在设计接口的时候要精简单一
  • 迪米特法则(law of demeter):降低耦合
  • 开放封闭原则(open close principle):对外扩展开放,修改关闭

六大原则的遵循,并不是是和否的选择,更不要刻意去追求,“物极必反,过犹不及”,灵活使用。
设计模式又分为创建型(工厂,单例),结构型(代理,组合),行为型(策略,观察者)等三个方面.

  1. 单例模式:一般会封装一个静态属性,并提供静态实例的创建方法
static singleton *__singleton = nil;
+ (singleton *)sharedSingleton {
static dispatch_once_t oneToken;

    dispatch_once(&oneToken, ^{

        __singleton = [[singleton alloc]init];

    });
    return __singleton;
}

其中static singleton *__singleton = nil;为静态变量,
类方法为(singleton *)sharedSingleton ,
dispatch_once_t 的函数是GCD提供的,在整个生命周期只执行一次
  1. 委托模式:委托是为了降低一个对象的复杂度和耦合度,使其能够具有通用性而将其一些处理置于委托对象中的编码方法,它通过delegate属性保持委托对象,使它来实现协议。那委托对象如何建立引用关系呢?对象.delegate = self。如一些复杂的控件(UITableView),除了实现委托协议,还需要实现数据协议,委托对象主要对控件对象的事件和状态作出响应,而数据源对象是为控件提供数据。
  2. 观察者模式:观察者模式中两个具体应用就是(通知,KVO),通知机制是“一对多”的对象间通信,不仅有本地通知还有远程通知。KVO是在对象属性发生变化时通知会被直接发送给观察者
  3. MVC模式:这个已经众所周知的了,其实它是一种复合设计模式,由(观察者+策略+组合)模式等组成,具体就是不同而异,可以用成MVP,MVVM,都是根据你项目来合理使用了。
分层架构设计

衡量一个软件架构的好坏是它的可复用性和可扩展性来满足用户不断变化的需求,我认为采用分层架构的设计,实现低耦合,高内聚。

  1. 表示层:用户与系统交互的组件集合
  2. 业务逻辑层:系统的核心业务处理层
  3. 数据持久层:数据持久层用户访问信息系统,对文件进行读写操作
  4. 信息系统层:系统的数据来源,可以是数据库,文件或者网络数据等

组件化、模块化、插件化

  • 组件:强调复用,避免重复造轮子。在开发过程中,一些核心技术或者常用框架,出于安全性和稳定性的考虑,不想被外界知道,所以会把核心代码打包成库,只暴露出头文件以供使用。
  • 模块:强调职责,这是一个可实现的单元,其核心是内聚和分离,如登录注册可分离成独立的模块
  • 插件化:强调化大为小,插件化在运行时合并模块。

组件模块化思想是软件开发的基本思想,组件化的目的就是复用代码模块,解除业务和代码的耦合,组件间彼此分离,便于开发,测试,维护和独立编译。解决主工程打包时组件间重复引用的问题,引入bridge组件库或pod添加,避免组件间直接耦合,具体请看:https://www.jianshu.com/p/210825875f39

质量监控

有时会说“没有崩溃,就没有我”,在快速迭代的过程中可能因为主观原因,如技术有限,知识盲点,粗心导致的crash,或者客观原因版本升级,手机卡顿,网络卡顿等导致的crash。虽然我们不能阻止崩溃,但我们可以去发现它,分析它,解决它。一套完美的质量监控应该包括:基本验证,稳定性,兼容性,安全性,功能测试和线上质量检测

  1. 基本验证:版本号,签名,账号,代码质量等
  2. 稳定性:一些性能指标,如CPU,内存,流畅度,包大小,启动时间,响应速度等
  3. 兼容性:多版本适配,多网络,低电量等
  4. 安全性:加密,解密。恶意攻击等
  5. 功能测试:单元测试,自动化测试
  6. 线上质量检测:用户反馈,crash收集,数据统计等

有一些验证是需要人工的,但是有一些可以通过自动化的,去尝试写一些脚本保证质量过关,当然也可以选择一些好用的第三方平台。

  • 关于线下性能监控:苹果公司官方就有一个性能监控工具 Instruments。它是一款被集成在 Xcode 里,专门用来在线下进行性能分析的工具.Instruments 的功能非常强大,比如说 Energy Log 就是用来监控耗电量的,Leaks 就是专门用来监控内存泄露问题的,Network 就是用来专门检查网络情况的,Time Profiler 就是通过时间采样来分析页面卡顿问题的。
  • 对于线上性能监控:监控代码不要侵入到业务代码中,采用性能消耗最小的监控方案,主要集中在 CPU 使用率、FPS 的帧率和内存这三个方面

CPU

<!--cpu_usage 就是 CPU 使用率-->


+ (integer_t)cpuUsage {
    thread_act_array_t threads; //int 组成的数组比如 thread[1] = 5635
    mach_msg_type_number_t threadCount = 0; //mach_msg_type_number_t 是 int 类型
    const task_t thisTask = mach_task_self();
    //根据当前 task 获取所有线程
    kern_return_t kr = task_threads(thisTask, &threads, &threadCount);
    
    if (kr != KERN_SUCCESS) {
        return 0;
    }
    
    integer_t cpuUsage = 0;
    // 遍历所有线程
    for (int i = 0; i < threadCount; i++) {
        
        thread_info_data_t threadInfo;
        thread_basic_info_t threadBaseInfo;
        mach_msg_type_number_t threadInfoCount = THREAD_INFO_MAX;
        
        if (thread_info((thread_act_t)threads[i], THREAD_BASIC_INFO, (thread_info_t)threadInfo, &threadInfoCount) == KERN_SUCCESS) {
            // 获取 CPU 使用率
            threadBaseInfo = (thread_basic_info_t)threadInfo;
            if (!(threadBaseInfo->flags & TH_FLAGS_IDLE)) {
                cpuUsage += threadBaseInfo->cpu_usage;
            }
        }
    }
    assert(vm_deallocate(mach_task_self(), (vm_address_t)threads, threadCount * sizeof(thread_t)) == KERN_SUCCESS);
    return cpuUsage;
}

FPS

<!--对 FPS 的监控也可以比较简单的实现:通过注册 CADisplayLink 得到屏幕的同步刷新率,记录每次刷新时间,然后就可以得到 FPS-->
- (void)start {
    self.dLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(fpsCount:)];
    [self.dLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
}

// 方法执行帧率和屏幕刷新率保持一致
- (void)fpsCount:(CADisplayLink *)displayLink {
    if (lastTimeStamp == 0) {
        lastTimeStamp = self.dLink.timestamp;
    } else {
        total++;
        // 开始渲染时间与上次渲染时间差值
        NSTimeInterval useTime = self.dLink.timestamp - lastTimeStamp;
        if (useTime < 1) return;
        lastTimeStamp = self.dLink.timestamp;
        // fps 计算
        fps = total / useTime; 
        total = 0;
    }
}

内存


<!--苹果公司介绍说 phys_footprint 才是实际使用的物理内存。-->

struct task_vm_info {
  mach_vm_size_t  virtual_size;       // 虚拟内存大小
  integer_t region_count;             // 内存区域的数量
  integer_t page_size;
  mach_vm_size_t  resident_size;      // 驻留内存大小
  mach_vm_size_t  resident_size_peak; // 驻留内存峰值

  ...

  /* added for rev1 */
  mach_vm_size_t  phys_footprint;     // 物理内存
  ...

<!--取出 phys_footprint 字段的值,就能够监控到实际物理内存的使用情况了-->
  
uint64_t memoryUsage() {
    task_vm_info_data_t vmInfo;
    mach_msg_type_number_t count = TASK_VM_INFO_COUNT;
    kern_return_t result = task_info(mach_task_self(), TASK_VM_INFO, (task_info_t) &vmInfo, &count);
    if (result != KERN_SUCCESS)
        return 0;
    return vmInfo.phys_footprint;
}

东西不多,但很实用。接下来我会详谈项目中的网络请求,性能优化和一些高级知识点的总结

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352

推荐阅读更多精彩内容