0%

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

从校园到实习

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

大三上的实习当时自己错过了机会,只进入了一个普通的互联网公司,但是也学到了更多校园中无法见到的东西(比如多移动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} $

阅读全文 »

最近一段时间到南京某公司实习之后,就一直没有更新博客,而校招季节到来,也是投了几家公司,之前不发面经是担心有泄题之类的风险,而且自己也需要调整一下心态。而现在,终于可以谈谈iOS开发的面试了

面试技术栈

技术岗位面试,基本上离不开这三方面的东西:

  • 数据结构与算法
  • 语言/框架方面基础知识
  • 通用知识,项目

所以今天专门整理了一些最近的面试中遇到的问题,对自己的能力也正确的评价一下

#数据结构与算法

阅读全文 »

Objective-C中的block是一种特别的结构,block与普通的instance不同的地方,不止更在于它的语法,更在于它的不同表现以及内存分配。

虽然block对于Objective-C来说已经早不新鲜了,但现如今很多博文讲述的block行为是基于MRC的,这与ARC下的表现是不同的。现代Objective-C也应该渐渐淘汰MRC和GC(其实GC已经淘汰了,在macOS Sierra已经无法使用,iOS从来不支持)本文所提及情况均限于ARC

ARC下不同类型的block表现

很多博文都提到过,block通过llvm编译后,会生成对应的三种Class的实例变量,分别是:NSStackBlockNSGlobalBlockNSMallocBlock,分配区域分别位于进程的栈,TEXT段,堆。ARC下为了简化block的内存管理,以及性能优化,llvm会对不同情形下的block进行不同的类型变化,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int a = 1;
NSString *string = @"";

NSLog(@"%@", NSStringFromClass([^(){} class]));

NSLog(@"%@", NSStringFromClass([^(){
int b = a;
} class]));

void (^block1)(void) = ^{
int b = 2;
};
NSLog(@"%@", NSStringFromClass([block1 class]));

void (^block2)(void) = ^{
NSString *b = string;
};
NSLog(@"%@", NSStringFromClass([block2 class]));

猜猜输出是什么?

阅读全文 »