iOS 创建对象的姿势

在写 iOS 代码的时候,怎么样去 new 一个新对象出来,都有一些讲究在里面。使用不同的姿势去创建对象,对后期维护所造成的影响会存在细微的差别。 init 创建 在之前一篇分析 iOS 代码耦合的文章中,提到过当我们给一个对象的 property 赋值的时候,通过 init 方法传入参数来初始化 property 会让我们的代码更可靠。 有些人在定义带 property 的 clas...

iOS代码设计中的开放与封闭

我们至今所写的 iOS 代码都是遵循 OOP 这种编程范式,以对象来临摹和表达我们对于世界的理解。在设计类的时候,恪守 SOLID 五个原则会让我们的代码更易拓展和维护。SOLID 中的 O 代表的是 Open/closed principle,这篇文章所要探讨的不仅仅是类设计中的 Open 和 Closed,而是要站在更广阔的视角来看待代码中的开放与封闭。 前言 我们作为代码工作者,不...

一名iOS程序员眼中的「小程序」

小程序如约和大家见面了,就这两天的势头来看,可以说是「好评如潮」了。Peak君今天也和大家闲聊下,这小程序和我们iOS程序员之间的关联。 初步观感 初体验非常棒,试用几个小程序之后,感觉在流畅度和响应时间上都属上乘,整体水准非常接近Native的体验,客户端团队应该下了不少功夫,Peak君已经听到了身边好几个朋友的溢美之词了。 小程序的入口现在位于第三个Tab页,单从这一入口深浅来说,...

危险的UITableView

如果把我们所做的UI做个简单分类,大致上可以分为列表界面和非列表界面。对于列表类UI,我们可以选择UITableView或者UICollectionView来实现。UICollectionView出现之前,UITableView几乎是唯一的选择,这每日可见人人都用的UITableView里隐藏着容易忽视的危险。 同步VS异步 同步和异步是基础的编程概念,也是贯穿于我们日常的两种代码书写方...

iOS编程中throttle那些事

不知道大家对throttle这个单词是否看着眼熟,还是说对这个计算机基础概念有很清晰的了解了。今天就来聊聊和throttle相关的一些技术场景。 定义 我经常有一种感觉,对于英语这门语言的语感,会影响我们对于一些关键技术概念的理解。有时候在学习新技术知识的时候,我会先花一些时间去了解术语英文单词的各种语义,在形成强烈清晰的语感之后,再去深入具体的技术语境。throttle也算是个生僻的单...

iOS当中的Cache设计

Cache的设计是个基础计算机理论,也是程序员的重要基本功之一。Cache几乎无处不在,CPU的L1 L2 Cache,iOS系统的clean page和dirty page机制,HTTP的tag机制等,这些背后都是Cache设计思想的应用。 为什么需要Cache Cache的目的是为了追求更高的速度体验,Cache的源头是两种数据读取方式在成本和性能上的差异。 在开始着手设计Cach...

2016年写文章总结

今天是2016年最后一个工作日,给自己做篇写文章的总结,同时也把过去一年的文章分门别类下,方便大家阅读。 年初的时候,定了两个小目标: GitHub上赚1000颗星星 坚持写技术博客 现在看来,总算没以工作忙为借口,把这两个都给实现了,尤其是写博客,最后的结果甚至超过原本的计划(庆幸脸)。 先晒下我收集的星星: 之所以要在GitHub齐集1000颗星星,纯粹是出于那...

如何用Xcode8解决多线程问题

Xcode 8诞生有段时日了,不知道大家对其中的新Feature是否都学习过一遍了,今天给大家介绍下Xcode 8中一个很实用的特性,Thread Sanitizer,用来解决平时编写代码时难以调试的多线程问题,顺道梳理下一些常见的容易混淆的多线程概念。 Thread Sanitizer 这款工具集成在Xcode 8中,主要帮助定位多线程相关的问题,还没有了解过的同学可以先查看 WWDC...

iOS代码耦合的处理

耦合是每个程序员都必须面对的话题,也是容易被忽视的存在,怎么处理耦合关系到我们最后的代码质量。今天Peak君和大家聊聊耦合这个基本功话题,一起捋一捋iOS代码中处理耦合的种种方式及差异。 简化场景 耦合的话题可大可小,但原理都是相通的。为了方便讨论,我们先将场景进行抽象和简化,只讨论两个类之间的耦合。 假设我们有个类Person,需要喝水,根据职责划分,我们需要另一个类Cup来完成喝水...

从Swift看Objective-C的数组使用

状态维护是个怎么说都不够的话题,毕竟状态的处理是我们整个App最核心的部分,也是最容易出bug的地方。之前写过一篇以函数式编程的角度看状态维护的文章,这次从Swift语言层面的改进,看看Objective C下该如何合理的处理数组的维护。 Objective C数组的内存布局 要了解NSArray,NSSet,NSDictionary这些集合类的使用方法,我们需要先弄明白其对应的内存布局...

2016年iOS技术圈回顾

2016年同2015年一样,在我还没有做好心理准备的时候,一晃神就到了年底。年关将近,不知诸君心情如何,年初的规划实现了多少,来年的计划又是否已有了眉目。年过三十的Peak君感觉年关是越来越难过了,越喧嚣的时候越想静处,感慨越多能说出口的反而越少。 近来有读者问Peak君为何最近这么多产,原因无他,仅为缓解年关将近的焦虑感。今年要说有什么收获,该算发现坚持写字所带来的好处。最近感觉尤其明显...

iOS关于时间的处理

做App避免不了要和时间打交道,关于时间的处理,里面有不少门道,远不是一行API调用,获取当前系统时间这么简单。我们需要了解与时间相关的各种API之间的差别,再因场景而异去设计相应的机制。 时间的形式 在开始深入讨论之前,我们需要确信一个前提:时间是线性的。即任意一个时刻,这个地球上只有一个绝对时间值存在,只不过因为时区或者文化的差异,处于同一时空的我们对同一时间的表述或者理解不同。这个...

扒一扒HTTP的构成

HTTP全称为HyperText Transfer Protocol,从名字不难看出这是一种基于文本的网络协议,对于初学者来说比较友好,容易上手。各平台上的一些第三方库都对HTTP做了进一步的封装,让HTTP变得更加亲民,但往往拿来就用的技术,很容易忽视其背后隐藏的细节。今天一起来扒一扒HTTP到底是如何构成的。 初窥全貌 HTTP第一眼看上去非常简单,先来看看Request部分: ...

iOS与函数式编程

有时候,一个关键字就是一扇通往新世界的大门。两年前,身边开始有人讨论函数式编程,拿关键字Functional Programming一搜,全是新鲜的概念和知识,顺藤摸瓜,看到的技术文章和框架也越来越多。 我有个习惯,在接收新知识的时候,我都会用已有的知识去做对比,我更关注新事物能对现有产品和知识体系带来哪些好处。 计算机发展到今天,已经很久很久没有理论层面的升级了,现今绝大部分新的知识都...

开车啦!一键爬知乎各种爆照

这是一篇严肃的技术分享文章,旨在向大家介绍一些网络安全方面的知识,及相关工具的使用。闲话少说,直接进入正题。 实现目标 知乎上经常有各种爆照及钓鱼贴,类似「胸大是一种什么样的体验?」, 「女生有翘臀是什么样的体验?」等。其实大家关心的只有照片,是不是? 我们的目标是在终端输入: ./get.sh 胸大 就能从知乎将胸大(或者其他关键词)相关的话题回答中的图片,一键下载到本地的文...

正确使用多线程同步锁@synchronized()

在上篇多线程安全的文章中,我曾推荐过大家使用@synchronized来使得代码获得原子性,从而保证多线程安全。这篇文章向大家介绍一些@synchronized的知识点和应该避免的坑。 @synchronized原理 @synchronized是几种iOS多线程同步机制中最慢的一个,同时也是最方便的一个。 苹果建立@synchronized的初衷就是方便开发者快速的实现代码同步,语法如...

iOS多线程到底不安全在哪里?

iOS多线程安全的概念在很多地方都会遇到,为什么不安全,不安全又该怎么去定义,其实是个值得深究的话题。 共享状态,多线程共同访问某个对象的property,在iOS编程里是很普遍的使用场景,我们就从Property的多线程安全说起。 Property 当我们讨论property多线程安全的时候,很多人都知道给property加上atomic attribute之后,可以一定程度的保障多...

如何深度重构UIViewController实例-直播界面

之前写过一篇深度重构UIViewController,中间简单的提到过我现阶段是如何重构Controller这一层的。之后不少同学联系我索要demo代码,果然是no code, no BB。 抽空把之前做过的一个直播App Controller这一层抽离出了一个简单的demo,把关键的和业务相关的代码全部去掉了,剩下一个列表和直播界面,但能从中看出完整的流程。 重构思路 重构的思路在之...

和Charles同样强大的iOS免费抓包工具mitmproxy

现阶段给iOS设备进行网络抓包的手段非常之多,除了我之前介绍的tcpdump,wireshark之外,还有Charles,以及和Charles同样好用的mitmproxy,其实还有更多,比如更小众的debookee。似乎知道Charles的同学更多一些,但其实Charles有的功能mitmproxy基本都有,mitmproxy还免费,而且对于terminal用户来说使用起来更亲近。 如何使...

Wireshark抓包iOS入门教程

网络抓包是个基础技能,对于网络协议的掌握有一定的要求。iOS上实现网络抓包可以用Charles(针对http和https),tcpdump(快速分析网络包),和Wireshare。之前写过一篇介绍tcpdump抓包的入门文章,和tcpdump相比,Wireshark提供丰富的GUI交互,而且能分析所有的网络协议,关键还是免费的,掌握好Wireshark就能应付绝大部分需要分析网络协议的场景了...

Http文件上传进度为什么不准

做过客户端文件上传的同学会明白,基于HTTP的文件上传并没有看起来那么简单。按我过去经验,至少有两块工作会比看上去要麻烦一些,第一个是断点续传,第二个是进度展示。断点续传想要优化的好要花不少力气,后面有机会再写,这篇先看上传进度的问题。 首先说现象:我们调用第三方http framework上传文件的时候,都会有API回调告诉我们上传的具体进度,这个进度值都是不准的。 比如下面代码使用a...

UILabel中一个很多人都会踩的坑

一个很严肃的问题,平常你是怎么设置UILabel的高度的? 我见过不少如下普遍的写法: UILabel *lb = [UILabel new]; lb.text = @"gyjq"; lb.font = [UIFont systemFontOfSize:30]; lb.backgroundColor = [UIColor clearColor]; [self.view addSubvie...

应届生应聘iOS岗位的面试建议

每年都有大量的应届毕业生投入到iOS开发大军当中,我过去3年也面试过不少应届生,总体感觉出类拔萃者相当稀少,泯然众人者还是占多数,大部分人对iOS技术面试会是什么样没什么概念,更不知道该怎么去准备一场面试。其实毕业季学校都留给了每个人充足的自由时间去准备学习,对于,仅以过来人提些切实可行的建议帮助刚毕业的同学们,以下这些建议花三个月准备绰绰有余。 相信自己的选择,全力以赴 在开始准备面试...

realm之于iOS

Realm是除了CoreData和Sqlite之外的第三个选择,一个近几年兴起的全新的数据库方案,一直保持着活跃的更新,而且引起了iOS开发圈广泛的关注。Realm到底好不好用,又有哪些闪光点呢?下面通过一个实际的demo综合比较CoreData和Realm在使用体验上的差别。 Realm Realm For iOS正式诞生于2014年左右,一开始就引起了不小的关注,两年多的快速迭代使其...

iOS端数据库解决方案分析

很早之前就想写一篇iOS端数据库相关的总结文章,梳理下使用移动端数据库的一些重要知识点,再综合对比下sqlite和CoreData的优缺点,希望能帮助一些这方面经历较少的同学少走一些弯路。 为什么要用数据库 iOS端持久化的方案选择比较多,NSUserDefault,Keychain,File,sqlite都可以帮助存储关键的业务数据。NSUserDefault和Keychain都是轻量...

一些NSArray,NSDictionary,NSSet相关的算法知识

iOS编程当中的几个集合类:NSArray,NSDictionary,NSSet以及对应的Mutable版本,应该所有人都用过。只是简单使用的话,相信没人会用错,但要做到高效(时间复杂度)精确(业务准确性),还需要了解其中所隐藏的算法知识。 在项目当中使用集合类几乎是不可避免的,集合类的使用场景其实可以进行抽象的归类。大多数时候我们需要将若干个对象(object)暂时保存起来,以备后续的业...

iOS开发之玩转蓝牙CoreBluetooth

之前详细谈过不少关于HTTP协议的知识点,TCP/IP也通过tcpdump做过简单的介绍,但网络协议的本质其实是连接,设备或者端之间连接的方式有多种,常见的http或者基于tcp的socket只是森林一叶,还有些不那么常见的协议比如蓝牙。适当脑洞,也能玩出不少新花样来。 关键概念 谈到蓝牙,很容易让人联想到蓝牙穿戴设备,好像听起来更靠近硬件层一些。苹果其实对iOS和OSX上的蓝牙已做了一...

iOS被忽视的Extension开发

估计现在有过iOS App Extension开发经验的朋友还不太多。说来惭愧,我也是最近以Extension的方式写过Xcode的一个插件之后,才把Extension相关的知识点梳理了一遍,技术和想法上都有些新的收获。顺便写篇文章介绍推广下App Extension开发。 何谓App Extension? iOS生态圈向来以其封闭性闻名,封闭一方面提高了第三方应用的质量,另一方面也使得...

深度重构UIViewController

UIViewController是iOS应用的基础业务单位,每个iOS程序员都写过无数的Controller。今天和大家一起来深度解剖Controller,看看怎么来做一次深度的重构。 重构的前提 我们应该谨慎的去重构我们的代码。iOS系统提供的UIViewController一定程度上可以很好的应付简单的页面单位,对于复杂的页面,我们也可以采用市面上主流的MV(X)系列模式,比如MVP...

一款Xcode合法插件EasyCode,快速生成代码

一直想着要做个新插件提升Xcode下写代码的效率,之前的FastStub虽然能省去很多方法的生成,但还是有不少“体力劳动”型代码要敲,这些天趁着空了一些新写了一款Xcode“合法”插件,之所以说合法,是因为Xcode 8开始禁用了之前所有的第三方插件,新开发的插件要通过安全性检验,必须使用官方的Xcode Editor Extension来做。这款EasyCode插件就是基于Extensio...

一次iOS App优化(踩坑)之旅

未经深思熟虑的优化是bug之源,这句话做过深度优化的同学一定能明白其中的辛酸。今天和大家分享下博主一次优化CoreText的填坑经历。记得那时候,iPhone 4s还算市面上的主流机型。 优化起因 当时正在做一款IM App,产品经理觉得每次第一次进入聊天界面的时候有点慢,而且进入之后的第一次滑动有点卡。正是由于慢和卡,导致了后面一系列的优化。在开始介绍优化方案之前,先说下「首次体验问题...

iOS网络请求在Controller退出后是否应该被取消?

一个编写iOS代码的经典场景:用户进入某个Controller,发起Http网络请求从Server获取数据,在数据返回之前用户退出了Controller。此时是否需要Cancel之前发出的网络请求呢? 如果请求的数据只在当前Controller产生内容,结论当然是需要Cancel,虽然我知道不少iOS程序员因为偷懒而忘了取消。我们用工程的思维,深入本质,一起看下这背后都发生了什么,如果不C...

深度优化iOS网络模块

几乎每一个讲究的iOS项目都会有一个「网络模块」,大部分的网络请求都是通过HTTP完成,使用成熟的第三方库诸如AFNetworking很容易搭建一个功能简易的网络模块。但这一模块要优化好却没那么简单,是个旷日持久的工作,笔者根据自己多年的“填坑”经验,总结一下深度优化iOS项目网络模块的方方面面,也给自己做下知识梳理。 预热 网络模块的接口设计不在本文讨论之列,设计思路有些偏个人口味,我...

iOS应用架构现状分析

iOS从2007年诞生至今已有近10年的历史,10年的时间对iOS技术圈来说足够产生相当可观的沉淀,尤其这几年的技术分享氛围无论国内国外都显得异常活跃。本文就iOS架构这一主题,结合开发圈里讨论较多的几种主流方式,再配以博主自己的理解,做下现状分析。给自己做下知识梳理的同时,也期望能引入新的思考。 架构的定义 过去6年多几乎绝大部分时间都浸淫在iOS平台,翻阅过不少关于架构的文章,发现众...

iOS应用UI线程卡顿监控

iOS设备虽然在硬件和软件层面一直在优化,但还是有不少坑会导致UI线程的卡顿。对于程序员来说,除了增加自身知识储备和养成良好的编程习惯之外,如果能一套机制能自动预报“卡顿”并检测出导致该“卡顿”的代码位置自然更好。本文就可能的实现方案做一些探讨和分析。先贴出最后方案的github地址。 解决方案分析 简单来说,主线程为了达到接近60fps的绘制效率,不能在UI线程有单个超过(1/60s≈...

一份"有点难"的iOS面试题

之前一时兴致在知乎上出过一份iOS的中级面试题,引起一些关注,不少同学表示对”隐藏关卡“感兴趣。升级版iOS面试题来了,目测难倒90%iOS程序员,目测一大波程序员撸着袖子在靠近。每道题都不难,对知识广度有要求,请摸着良心回答,不要百度。 声明:这份面试题和iOS程序员本身技术水平没任何关联,无论你能否全部答出,都不要对自己产生任何正面或消极的评价,权当做闲暇之余的消遣。 1.NSStr...

一个让脑子快速进入编程状态的小Tip

写代码是门耗费脑力的手艺活。普通人一天约有40%的身体能量被大脑消耗,作为大脑的重度使用者,程序员每天对大脑的使用率可想而知。 特别是像我这样的高龄程序员,如果昨晚熬夜加过班,第二天一大早很容易脑子昏昏沉沉。 有很多大众鸡汤可以帮助Refresh Brain。比如:保持充足的睡眠,每天一杯咖啡,使用GTD,番茄工作类app,听听轻音乐等等。 今天给大家介绍一款适合程序员的小Tip。 ...

iOS组件化方案

最近在思考团队扩张及项目数量增加的情况下,如何持续保障团队高效产出的问题,很自然的想到了组件化这个话题。重翻了前段时间iOS开发圈关于组件化的讨论,这里做下梳理和自己的思考。 组件化的驱动力 在开始讨论组件化技术方案之前,可以先思考下驱动项目组件化背后的原动力。我们假设这样一个场景,公司有 A,B,C三个项目在appstore运作,三个项目分别由Team A,Team B,Team C开...

书写高质量代码之状态维护

维护程序状态的一些小心得。 状态之始 我们第一眼接触新事物所触发的思考方式,决定了以后我们看待这样事物的角度,进而影响更深层次的理解和行为。 编程相对于人类历史的进程而言,不过是个六七岁孩童偶然捡到的新玩具,因为新鲜好玩到现在都还爱不释手。这个玩具于我们的大脑会产生怎么样的化学反应是个未知数,每个个体都不同。你第一眼见到色彩或形状直接关系到你的兴趣点或是以后会怎样去把玩这个玩具。 小...

iOS内存泄漏自动检测工具PLeakSniffer

新款objective-C内存泄漏自动检测工具PLeakSniffer,GitHub地址。 背景 前些天读到WeRead团队分享的一款内存泄漏检测工具MLeaksFinder,恍惚想起早些时候自己也有过编写这样一个小工具的想法,不知道由于什么原因把这事给忘记了。在仔细读过MLeaksFinder源码,了解实现思路之后,发现和自己最初的想法并不相同,终于在上个周末战胜拖延症将之前的想法付诸...

纯IPv6环境App适配的坑

苹果从2016年6月1号开始,强制所有app必须支持纯IPv6的网络环境。这项举措将对IPv6的普及起到一定的推动作用,也体现了Apple作为国际大厂的担当。 大部分App由于使用的是高层API,并不需要做任何的更改就能自然度过这次IPv6的考核,只是对于少部分手写IPv4地址连server的同学,生活有一点点影响。 请好好学习TCP/IP协议 每次苹果对技术的推动,都是一次很好的充电...

一只快速生成代码的Xcode插件FastStub

插件github地址,这款插件的灵感来源于Android Studio,在AS当中按 cmd+N 可以呼出generate code菜单,快速生成一系列模板代码。比如自动解析出super class当中还没有被override的方法,比如自动生成Constructor,并选择要传入的参数等。 插件原型 在Android Studio中可以这样重载父类的方法。 支持多选,按回车一键插...

用Swift搭建数据驱动型iOS架构

上篇博客里介绍了一种架构iOS App应用层的方式,Context Driven Design。CDD可以让应用层UIViewController的结构以细粒度,低耦合的方式组合,不过CDD只能适用于应用层,对于具备一定业务规模的App来说有些捉襟见肘。这次我们尝试来用Swift搭建一个完整的数据驱动型架构,这种架构将有更清晰的层次结构和数据流向,当然也能支撑更复杂的业务系统。核心思想是基于...

iOS应用层架构之CDD

从2010年开始接触iOS开发到现在,折腾过不少app的架构。从MVC到MVVM,VIPER,MVP,以及最新的ReactiveCocoa都做过实战尝试,还有其他变种,诸如猿题库iOS客户端架构设计,也做过一些学习研究。这些技术概念如果不熟悉,建议每个链接都点开好好研读下,不要对你的大脑太温柔。在开始架构讨论之前,再推荐一些其他非常值得一读的文章:唐巧-被误解的 MVC 和被神化的 MVVM...

iOS,Android网络抓包教程之tcpdump

现在的移动端应用几乎都会通过网络请求来和服务器交互,通过抓包来诊断和网络相关的bug是程序员的重要技能之一。抓包的手段有很多:针对http和https可以使用Charles设置代理来做,对于更广泛的协议可以使用tcpdump或者wireshark。wireshark提供GUI,方便做深入全面的数据分析。tcpdump则输出原始的包内容,好处是快速高效,之前写过一篇简单的微信红包图片的破解教程...

微信iOS朋友圈红包图片抓包教程

使用mac系统自带tcpdump即可以抓包获取朋友圈的红包图片内容。不需要第三方软件,步骤如下: 第一步:将手机usb连接itunes,获取iphone设备的udid: 第二步:开启终端(terminal)并输入rvictl -s 418d838461a891b5d7161a05a163888c9f107780。把418d838461a891b5d7161a05a163888c9f1...

iOS网络请求优化之DNS映射

绝大多数网络请求的第一步都是DNS解析,解析请求根据当时网络情况不同,各平台的DNS缓存策略差异等因素,对移动端app整体网络性能会产生或大或小的影响。移动端app网络性能优化涉及到很多方面,DNS映射只是其中一环,也是十分重要的一环,因为它带来的好处不仅仅是降低网络请求的延迟。 降低DNS请求带来的延迟 客户端app的请求第一步都是DNS解析,但由于cache的存在使得大部分的解析请求并...

iOS 中级面试题

半年前在知乎浏览到一个帖子,是关于如何面试iOS工程师。由于当时公司正在招聘iOS工程师,自己也面试了不少同学,就饶有兴致的把自己的面试问题清单贴了出去,却意外的引来了不少关注。还有不少同学认真回答并将答案私信于我交流的,还有求隐藏关卡的:(。由于工作太忙,私信和评论后面都没怎么回复,这里一并做下总结回复:p 一份面试题的意义 我把收到的私信和一百多条评论都仔细读了遍,发现大家之所以会关注...

iOS Push的门道

iOS在诞生之初为了最大程度的保证用户体验,做了一些高瞻远瞩且影响深远的设计。APNs(Apple Push Notification service)就是其中一项。 基本功 早期iOS设备的内存和CPU资源都很有限,为了让前台活跃的app拥有尽可能多的系统资源,以及节约设备电量,iOS一开始就“不允许”普通app的进程常驻后台。这个决定很大程度上保障了用户体验和延长了手机的待机时间,但...