面试的时候你可能碰到面试官设的各种坑:不止喜欢问你iOS开发的一些特性和方法,更喜欢喜欢问你这些特性及方法你觉得它是怎么实现的?你觉得苹果公司为什么要这样设计?
也许面试官自己也没自己实现过,毕竟有些东西苹果为什么这样设计,若不是苹果公司的工程师无法知道。
但作为面试者,这个些问题正是拉开差距的最好办法:不一定要你亲手用C去重现苹果的机制,但可以谈谈你的见解和看法。所以,这一块最好有个准备。
1. 用法实践篇
一般,会问你怎么实现某个模块,用过哪些API,介绍下他们的用法。
1.1 你以前的项目架构是怎样的?
- 我用的MVVM,相对于传统的MVC,主要区别就是把网络请求和业务层放到ViewModel里面了。
- 相对于普通博客介绍的
View<->ViewModel <->Model
,其实更靠谱的理解是View <-> C <-> ViewModel <->Model
,把Controller加进去,更好的理解。
- 然后,为了让View和ViewModel之间能够有比较松散的绑定关系,于是我们使用ReactiveCocoa,KVO,Notification,block,delegate和target-action都可以用来做数据通信,从而来实现绑定,但都不如ReactiveCocoa提供的RACSignal来的优雅,如果不用ReactiveCocoa,绑定关系可能就做不到那么松散那么好,但并不影响它还是MVVM。
- 这里推荐一个MVVM基础框架:https://github.com/foxsofter/LPDMvvmKit。
1.2 你是如何数据建模的?
- 普通的办法就是建一个基类比如BaseModel,里面写好一些初始化的方法,然后新建一个子类比如UserModel,里面写好一些跟后台对应的字段,用它来接收数据或者保存数据。这一块可参考:https://www.jianshu.com/p/923404fcd2f2
- 还有一种办法,就是封装一个功能,根据网络请求返回来的JSON数据自动生成Model文件,当然也提供特许字段的处理,比如
id
字段。它的缺点就是如果接口的JSON的数据是动态可变的,还是需要手动调整补充。这个可参考:https://blog.csdn.net/lg767201403/article/details/78675788 - 当然,还有一种办法,就是有个软件叫JSONExport,可以实现上面封装的那个功能,不过这种方法生成的更慢。
1.3 你怎么实现字典转模型的?
- 我原来的老工程里面用的是MJExtesion,它的兼容性更高。当然JSON层数不多的时候,我也会自己实现字典转模型,主要利用两个API:
- (void)setValuesForKeysWithDictionary:(NSDictionary<NSString *,id> *)keyedValues;
和
- (void)setValue:(id)value forUndefinedKey:(NSString *)key{}
当然,还有YYModel也可是实现字典转模型,它的效率更快,关于这两个的性能对比研究,可查阅https://www.jianshu.com/p/ef3baf1c9463。
关于自己手动实现字典转模型的原理,就是利用runtime+kvc,关于这一块的研究,可查阅读者的另外一篇https://www.jianshu.com/p/885b65688b96。
1.4 你用过哪些动画效果?
- 最基本的就是UIView动画了,不涉及任何CAAnimationtion提供的API,这个就包括了两类frame动画(涉及一些frame, bounds, center的改变),transform动画。关于它的取值可以这样:
imageContainView.frame = CGRectMake(80, 80, 200, 200);
- frame动画基本利用的属性就是UIView的
.frame
,.bounds
,.center
属性。 - transform动画利用的就是UIView的
.transform
属性。至于它的取值可以类似如下这样,只要CGAffineTransform类型即可。
self.redView.transform = CGAffineTransformTranslate(self.redView.transform, 0, 0);
self.redView.transform = CGAffineTransformMakeRotation(M_PI);
self.redView.transform = CGAffineTransformMakeScale(1.5, 1.5);
- 当涉及一些frame, bounds, center的改变或是形变的时候其实可以用 transform方式 来取代 frame方式。
- UIView动画基本的语法形式就是两种,一个是UIView的begin --- commit,一个是UIView的animations block了。
- 再就是直接利用核心动画CAAnimation及其子类的API了,包括基础动画,组动画,转场动画,关键帧动画,形变动画。这种动画的基本形式就是新建一个CAAnimation子类例如
CAKeyframeAnimation
,然后向animatedView.layer视图添加动画效果
/**
* 抖动效果
*/
-(void)shakeAnimation{
CAKeyframeAnimation *anima = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];//在这里@"transform.rotation"==@"transform.rotation.z"
NSValue *value1 = [NSNumber numberWithFloat:-M_PI/180*4];
NSValue *value2 = [NSNumber numberWithFloat:M_PI/180*4];
NSValue *value3 = [NSNumber numberWithFloat:-M_PI/180*4];
anima.values = @[value1,value2,value3];
anima.repeatCount = MAXFLOAT;
[_demoView.layer addAnimation:anima forKey:@"shakeAnimation"];
}
- CG动画,比如我实现过一个类似芝麻分半圆形动画的效果。这个动画中,色彩渐变是通过
CAGradientLayer
实现的,设置好参数后,设置它的蒙层即可,例如gradientLayer.mask = self.graView.layer;
。关于,CG绘制的具体代码,可参考如下: