category 是 OC 2.0后添加的新特性,主要作用是给已经存在的类添加方法,当然秉着类的单一职责原则和接口隔离原则我们通常会将不同功能的类扩展分别写在不同的文件中,这样不仅减少了单个文件的体积,同时可以对 category 进行按需加载。

category 的定义

所有的 OC 类和对象在 runtime 层其实都是 strcut,比如 objc_class、objc_object, 甚至 block(__block_impl) 还定义有自己的 isa 指针,category 也是如此。

1
2
3
4
5
6
7
8
typedef struct category_t {
const char *name;
classref_t cls;
struct method_list_t *instanceMethods;
struct method_list_t *classMethods;
struct protocol_list_t *protocols;
struct property_list_t *instanceProperties;
} category_t;
Continue reading

这段时间可能所有的开发 iOS 的公司都在做应用的 HTTPS 适配,因为在 WWDC 16 中,Apple 表示从 2017 年 1 月 1 日起,所有的新提交 app 默认是不允许使用 NSAllowsArbitraryLoads 来绕过 ATS 限制的,也就是说,我们最好保证 app 的所有网络请求都是 HTTPS 加密的,否则可能会在应用审核时遇到麻烦。

由于 Apple 在这之前预留了足够的时间让我们来进行网络适配,所以在这之前我们大部分情况下将 NSAllowsArbitraryLoads 设置为 YES,这样网络请求不受 ATS 的限制了。

Continue reading

关于 TCP 流与包的概念

首先需要明确一个概念,TCP 是以二进制流式传送数据的,既发送端与接收端成功建立连接下即可以不停的发送数据包,不同数据包间并没有明确的边界定义;而 UDP 发送数据的时候是按照一个一个的数据包去发送的。所以 TCP 发送数据是一个二进制流,而管道内的数据是一个个封装好的数据包。另外很重要的一点是,无论是发送端发送数据,还是接收端接收数据,都存在一个数据的缓冲区,而当发送端等待缓冲区满才发送数据,就会造成缓冲区有多个数据包,数据包可能会在开启 Nagle 算法的情况下进行合并发送;而接收端不及时处理缓冲区的数据包时,既同样造成缓冲区存在多个数据包,应用层可能会一次 read 完多个数据包。所以在发送端,我们需要对数据按照事先约定好的协议进行合理的封装,在接收端,我们需要按照协议对数据进行拆分。

Continue reading

对于一个开发者来说, MVC 设计模式被广泛应用于各种语言的开发中,这在 iOS 开发中体现的尤为多,比如我们的控制器 Controller,视图 View,模型 Model,从名称中就可以体现出各自的作用及分工,Apple 也是推荐我们使用 MVC 模式进行程序设计及开发。其实绝大部分时候 MVC 模式基本是可以满足我们的业务需求的,可是随着业务的膨胀,开发人员变动等因素,MVC 模式也暴露了其弊端,当控制器层变得越来越臃肿的时候,业务过于集中到控制器层,就会为为接下来的开发带来不便及代码的可维护性变低。

所以这时候为了解决刚才的问题,MVVM 模式就“应孕而生”了,它不仅仅可以对原有 MVC 模式进行代码上的优化瘦身,更重要的一点是兼容 MVC 模式,我们可以对原有项目必要的地方进行 MVVM 模式的升级。

Continue reading

整理了开发中一些特定场景下使用 RAC 的便利之处,关于一些常用的 API 的使用网上的资源还是很多的,就不做举例了。

  • 比如登录页面当用户输入的账号、密码长度合法的情况下才可以点击登录按钮,否则按钮不可点击,这里条件比较简单,即账号密码长度都大于5,其实还可以使用一些正则匹配账号格式是否正确等。combineLatest 就是合并多个信号,且每个信号至少发送过一次 sendNext,才会触发合并信号。
1
2
3
RAC(self.loginBT, enabled) = [RACSignal combineLatest:@[self.accountTF.rac_textSignal, self.passWordTF.rac_textSignal] reduce:^(NSString *usernameValid, NSString *passwordValid) {
return @(usernameValid.length > 5 && passwordValid.length > 5);
}];
Continue reading

ReactiveCocoa 是一个 iOS 中的函数式响应式编程框架,现在已经发展到了 v4.x,开始支持 Swift 了。如果我们的项目还是 Objective-C 开发的话建议使用 v2.5,也是一个很稳定的版本。当然每当我们学习一个新的框架前,除了了解简单的 api 接口使用外,另外很重要的一点就是要思考作者所表现的编程思想。

首先 ReactiveCocoa 是一个响应式编程范式,既 FRP(Functional Reactive Programming),简单讲在程序开发中:a = b + c,传统的命令式编程中赋值之后 b 或者 c 的值变化后,a 的值不会跟着变化,而在响应式编程中,a 的值会随着 b 或者 c 的值变化而变化。

另一方面 ReactiveCocoa 作者大量了使用了链式编程和函数式编程,使用过 Masonry 框架的应该都会有所体会,这样会使代码的可读性大大增强,代码更紧凑。

Continue reading

PhotoKit 中相关类介绍

  • PHAsset:代表一个照片库中的一个资源,如一个照片/一个视频
  • PHFetchResult:PHAsset 的集合,对应照片应用中的一个相册
  • PHFetchOptions:可以通过配置对资源进行排序,如时间
  • PHImageManager:用于从 PHFetchResult 中获取 PHAsset,可以设置相关参数,获取视频/图片/或者将一个PHAsset转化为NSData
  • PHImageRequestOptions:获取 PHAsset 资源时的相关设置,获取资源的方式(同步/异步),资源的质量等。
Continue reading

众所周知,iOS 应用审核机制,所以当我们的线上应用面对突如起来的 bug 的时候会显得很手足无措,有时候仅仅可能就是添加一两行代码解决这个问题却要因为审核等待一周或者美国人过节就会有甚至更长的审核周期。所以hoxfix热修复的作用简直就是掉炸天的功能啊。而 JSPatch 就是这样一个极小的轻量级框架,它可以使用 JavaScript 调用任何 Objective-C 的原生接口,替换任意 Objective-C 原生方法。目前主要用于下发 JS 脚本替换原生 Objective-C 代码,实时修复线上 bug。

Continue reading

主要为阅读一些博客和书籍,对一些 UIKit 方便的性能优化的一些知识点进行了整理

尽量避免图层的混合

  • 避免使用控件的 opaque 属性将其透明,当然默认的情况下 UIVie 的 opaque 属性就是 true,同时尽量将UIView的背景颜色设置与其父控件相同且不是透明的
  • 没有特殊情况下不要设置控件的 alpha 值降低透明度
  • 使用 UIImage 尽量使用没有带 alpha 通道图片

图层的混合

首先对于像素点,屏幕上的每一个点就是一个像素,像素有R/G/B三种颜色构成,某些时候还要有 alpha 值。

举个栗子,我们将两个图层混合,上层的是蓝色(R=0/G=0/B=1),设置其透明度为50%,下层是红色(R=1/G=0/B=0),那么最终我们看到的效果将是紫色(R=0.5/G=0/B=0.5),这种颜色的混合,尤其上层的图层有透明度的时候,会小号一定的GPU资源,想避免这种情况,尽量直接将上层的图层透明度设置为100%,这样GPU就会忽略下面的所有图层,避免了过多不要的运算。

Continue reading

在iOS视频开发中,传统的方案可以直接使用系统的 MPMoviePlayerController 既可以直接将系统的播放页面掉出来,更贴心的为我们添加了控制条,全屏放大及暂停按钮。但是实际中我们可以需要针对播放器做更多的自定义设置,继而更多的是会采用 AVPlayer,因为 AVPlayer 提供了更为强大的功能,虽然在使用的过程会比较麻烦,但是确实能为我们的 app 提供更好的视频播放体验提供前提。

Continue reading
Author's picture

Bin Han

纸上得来终觉浅 绝知此事要躬行


Software Engineer


Hangzhou China