0%

虽然Swift现在是开发iOS推荐入手的最佳语言,但是对于代码库而言,最大的一个问题是Swift ABI仍然没有定下(今年发布的的Swift 4.0,依然放弃ABI稳定性,而注重于Swift源代码3.x->4.0的兼容性)。所以这就意味着Swift 3.x编译的二进制库,在Swift 4.0将无法链接,只能重新代码编译。看来这又将是Objective-C这门古老的语法,能够作为一些framework首选开发语言的一年。

对于一个代码库来说,有时候我们为了隐藏一些实现的细节,或者内部处理流程,需要编译到二进制进行分发,并提供Public Header来供其他开发者调用。

因此,开发代码库的时候,需要明确哪些API是对外公开的,可以由其他开发者调用。那些是库内部之间互相调用的,不应该由外部使用者调用。而Objective-C不像C++提供了private关键字来限制直接访问成员变量和成员方法。因此,就需要尽量避免私有属性和私有方法的定义出现在头文件中。只要不引入私有的头文件,那就无法直接访问这些属性和方法。

隐藏内部属性

私有属性,可以分成两种,一种是希望放到类内部而纯粹不想暴露给任何人的,可以叫做内部属性。一种是希望暴露到Private Header中,只限于引入该头文件的地方进行访问。

内部属性的声明非常简单,我们可以直接使用类扩展声明属性,而编译器会自动生成getter和setter,不需要任何额外工作。

阅读全文 »

对各种客户端来说,无论是Web还是移动端,图片占据的容量和传输资源一定是非常大的。对于静态图,我们常见的PNG和JPEG格式在压缩率和画质无损上都存在着不尽如人意的地方,而动图格式的GIF更是存在着很多问题,比如因此,在很多情况下,我们需要迁移到新的图片格式。

GIF

为什么我们不用GIF呢,GIF由于时代限制,存在的天生的问题。GIF的规范最新版本是在1989年制定的,一个24位色都没有普及的时代,因此,GIF规范只支持256色索引颜色,并且只能通过抖动、差值等方式模拟较多丰富的颜色。更为悲剧的是,它的alpha通道只有1bit,换言之,一个像素要么完全透明,要么完全不透明,而不像现在PNG的RGBA的8bit alpha通道,alpha值也可以和RGB一样都有255个透明值。这导致了所有GIF的图片带上透明度以后,边缘会出现明显的锯齿。所以如果你的客户端需要展示带透明度的动图,GIF基本上可以不考虑

实际的在线Demo,建议用Safari或者Chrome+插打开:http://apng.onevcat.com/demo

APNG

阅读全文 »

年后的最后一天,也是该总结一下这一年的成长了。

从校园到实习

软件专业的大三学年,如果你不考研留学的话,说起来都是会走实习加校招的流程。自己这年印象最深的,也就是整个下半年的实习,面试,以及现在的实习了。

大三上的实习当时自己错过了机会,只进入了一个普通的互联网公司,但是也学到了更多校园中无法见到的东西(比如多移动App多Project管理,MapKit,React Native),开阔了一点眼界。真正的下半年好几个月都在忙着校招面试相关的东西,从中也总结了一些经验吧(虽然不知道对社招是否有帮助)。然而到现在,从南京来到了北京,提前过来头条这边实习。

实习开始都是兴奋和好奇的,因为可以看到公司的各种设施,福利,还有认识各式各样的人。来这边也是专门拉了两个同公司的应届生一起来,也挺愉快的。公司离得近,组里的人也都比较厉害(至少都是我请教别人教育的情形),虽然上班累了些,但是感觉自己成长也是非常的大,很难想象假如不来实习,全靠自己摸索,明年直接毕业过来上班自己是什么样的水平。

近期工作感想

阅读全文 »

ReactiveCocoa和RxSwift

iOS的开发上,Objective-C可以说既是一个巨大的成功,也是一个巨大的限制。Cocoa Touch提供的原生API本身就是目标当年的事件驱动和消息派发的GUI编程模型,并且专门为Objective-C这门类smalltalk的消息式OO语言设计的,更为尴尬的是iOS上没有OS X上自带的Data Binding。种种原因,导致Target-Acion,KVO,Notification,Apple式MVC架构才会一直成为iOS开发的主流。然而,做过开发的都知道,这套架构在大型App,尤其复杂是网络请求和人机交互特别多的情况下,非常容易让整个App架构变得难以维护。

Apple式的MVC,又称为Massive View Controller,会让你整个业务代码和UI绑定代码充斥同一个文件中,并且导致很多人经常会在View中,直接#include一个Modeld的头文件,然后起一个configureInfo: 的方法,直接在里面把Model的数据拿来绑定到View的属性上。不信?试试搜一遍你所有的View,把Model的头文件删掉,看看能否编译通过。

1
2
var userCell = tableView.dequeueReusableCellWithIdentifier("identifier") as UserCell
userCell.configureWithUser(user)

MVP架构或许是你的救星,不过实际上,MVP只是一个工程化的解决问题,把Massive View Controller变成Massive View Presenter,带来相对明确的架构分层的副作用就是近乎两倍的代码量。而在这种情况下,MVVM的架构就是一个非常大的突破,和MVP一样把View/ViewController扔到一起,但是引入单独的ViewModel,通过View到ViewModel的单向绑定,ViewModel对Model的订阅,既避免了MVC造成的代码混乱,又减少了MVP的造成的重复代码。而实践上,提到MVVM,就得 提到ReactiveCocoa或者RxSwift,这两者都是FRP的GUI框架实现。

ReactiveCocoa

阅读全文 »

熟悉做端GUI程序(客户端,Web前端)的同学一定会知道,做UI最大的问题就是模型和视图对象的绑定,视图对象的状态管理,以及事件消息的处理。

背景

传统的GUI编程的一大核心,就是使用了事件驱动编程模型。UI对象的布局、状态等,通过外部的消息事件(点击,触摸,网络请求响应等等)来触发。这是由于GUI程序的人机交互的天生性质决定的(当然,这里的GUI不包括游戏,游戏一般采用立即的帧驱动而非事件)。对于GUI编程的架构方面,从发现到现在,不外乎这几种:

传统的事件监听,消息派发机制:

这是最常见,也是最贴近GUI程序底层实现的模型。一般来说,GUI程序的框架入口就是一个大的while(true)循环,通过在循环内不断向窗口管理器请求消息(比如点击事件等用户输入),通过把底层的消息回调函数回调或者IPC机制,封装成一个个对开发者友好的事件对象来派发出来。

阅读全文 »

Core Animation 3D 仿射变换知识

之前写的Core Graphics是2D平面上的坐标变换,而iOS开发中,为了实现复杂的动画效果,视图切换效果,会用到很多3D变换,这就是Core Animation提供的CATransform3D,其中大部分API都和2D情况类似,但这里需要详细解释一下透视投影这个概念,和m34这个值的真实来源,一些博客抄来抄去却没有点到点子上,让人看不下去……

变换矩阵

1
2
3
4
5
6
typedef struct CATransform3D {
CGFloat m11, m12, m13, m14;
CGFloat m21, m22, m23, m24;
CGFloat m31, m32, m33, m34;
CGFloat m41, m42, m43, m44;
} CATransform3D;

这个结构体对应的是这样一个4x4的变换矩阵:

$ \begin{bmatrix} m11 & m12 & m13 & m14 \\ m21 & m22 & m23 & m24 \\ m31 & m32 & m33 & m34 \\ m41 & m42 & m43 & m44 \end{bmatrix} $

阅读全文 »

如今也是入了移动iOS开发的坑,最近不仅学习了Core Animation的部分知识,还接触到React Native,这一Facebook出品的React for Native Platform框架,其中React本身入门是相对简单的,而Redux入门就相对困难了,因此在这里总结一下,最后有自己写的Slides可以参考

背景

为什么需要Redux

  1. RN的state(可变,子组件不可见)和props(不可变,子组件可见)的设计,在面对大型项目时候,容易因为不经意修改state造成状态混乱,组件渲染错误
  2. RN使用了Virtual DOM,不需要Target绑定->Action修改UI属性,只要当状态变化,render新状态下的组件,数据单向传递,而MVC的设计模式存在双向数据流
  3. RN不易进行测试,Redux提供了非常方便的mock测试方式

准备

1
2
3
4
5
6
安装Redux:
npm install --save redux
安装React Native和Redux绑定库:
npm install --save react-redux
安装Redux Thunk异步Action中间件:
npm install --save redux-thunk
阅读全文 »

这是补充记录关于CG的几何变换的一些知识,涉及到简单的矩阵变换

变换矩阵

在Core Graphics进行图层缩放、旋转、平移的时候,本质的操作就是使用CGAffineTransform这个3x2矩阵对象,与我们的CGPoint这个1x2的矩阵(其实就是对应就是[x,y]这个向量)进行矩阵相乘操作,得到的新矩阵就是变换后的新向量。一般通过CALayer得到的图层都是矢量,因此可以把整个图层进行相应的缩放、旋转、平移。

1
2
3
4
5
6
7
8
typedef struct CGAffineTransform { 
CGFloat a;
CGFloat b;
CGFloat c;
CGFloat d;
CGFloat tx;
CGFloat ty;
} CGAffineTransform;

这个结构体对应的矩阵如下(看不到LaTeX公式的请看Apple Developer Document):

$ \begin{bmatrix} a & b & 0 \\ c & d & 0 \\ t_{x} & t_{y} & 1 \end{bmatrix} $

阅读全文 »