1. 有网络连接的应用中,在取得数据后将json字符串通过框架转换为NSDictionary或NSArray,很多人直接使用这些数据来更新UI,说出这样做的缺点,并给出解决办法?
- JSON 字符串通过框架转换为 NSDictionary 或者 NSArray 后, 就直接拿来用的缺点有:
- (1)在书写的时候有可能写错key值或者数组角标
- (2)扩展性不好,且不符合MVC的思想
-
- (3)会造成数据的重复下载,消耗用户的流量,降低用户体验;
- (4)如果没有网络或者网络堵塞,那么UI界面接收不到任何数据,显示不了任何内容,用户体验糟糕;
- 解决的办法
- 通过框架转换为字典或者数组后,再转化为模型,并进行二级缓存,需要显示的时候从沙盒中获取;
- 利用框架字典转模型进行重命名
- 利用框架截取我们需要的属性即可…
2. id声明的对象有什么特征?
- id是一个数据类型:
- id 声明的对象具有运行时的特性(动态数据类型),即可以指向任意类型的objcetive-c的对象,与C中的void*万能指针相似.
- 在编译阶段不知道它的真实是类型,运行时才能知道它的真实类型,所以id类型也不能使用点语法, 因为点语法是编译时特性, 而id是运行时特性
- 动态数据类型的特点:
- 在编译的时候编译器并不知道变量的真实类型, 只有在运行的时候才知道它的真实类型
- 如果通过动态数据类型定义变量, 如果访问了不属于动态数据类型的属性和方法, 编译器不会报错, 出错在运行时
- 通过动态数据类型定义变量, 可以调用子类特有的方法
- 通过动态数据类型定义的变量, 可以调用私有方法
- 弊端:
- 由于动态数据类型可以调用任意方法, 所以有可能调用到不属于自己的方法, 而编译时又不会报错, 所以可能导致运行时的错误
- 应用场景:
- 多态, 可以减少代码量, 避免调用子类特有的方法需要强制类型转换
- 避免动态数据类型引发的运行时的错误处理方法:
- 在调用这个对象的方法之前会进行一次判断, 判断当前对象是否能够调用这个方法
- isKindOfClass 判断指定的对象是否是某一个类, 或者是某一个类的子类
- isMemberOfClass 判断指定的对象是否是当前指定的类的实例
3. 你碰到过哪些导致程序闪退的原因?如何定位闪退的位置?
- 导致程序闪退的原因
- 1.函数无限递归
- 2.运行时,找不到方法(没实现)
- 3.访问了某个已经被释放的对象
- 4.程序占用内存或CPU过高
- 5.子线程阻塞主UI线程过久
- 6.从Bundle加载了不存在或者不支持的对象(图片素材之类的)
- 等等。。。。
- 定位闪退的位置
- 1.在设置断点的地方,选Add Exception Breakpoint。之后crash就会停在出错的位置。
- 2.如果是在测试阶段报错的话,可以在(设置-通用-关于本机-诊断与用量)里面看到崩溃的堆栈信息。
- 3.如果用rac的话,访问到已经释放了的内存,和内存警告这2种出错几率要高些。
4. 如何实现圆角矩形?有哪些方法可以实现扇形View?
-
圆角矩形:
- 直接修改view的样式,系统提供好的了
- view.layer.cornerRadius = 6;
- view.layer.masksToBounds = YES;
-
用layer做就可以了,十分简单。这个需要到库 QuartzCore.framework;
-
画矩形直接利用UIBezierPath给我们封装好的路径方法
- (x,y)点决定了矩形左上角的点在哪个位置
- (width,height)是矩形的宽度高度
- bezierPathWithOvalInRect:CGRectMake(x, y, width, height)
- [UIBezierPath bezierPathWithOvalInRect:CGRectMake(50, 50, 100, 100)];
- 圆角矩形的画法多了一个参数,cornerRadius
- cornerRadius它是矩形的圆角半径.
- 通过圆角矩形可以画一个圆.当矩形是正方形的时候,把圆角半径设为宽度的一半,就是一个圆.
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(50, 50, 100, 100) cornerRadius:50];
-
画扇形
- 画扇形的方法为:先画一个圆孤再添加一个一根线到圆心,然后关闭路径.
- 关闭路径就会自动从路径的终点到路径的起点封闭起下
-
用填充的话,它会默认做一个封闭路径,从路径的终点到起点.
-
首先要确定圆才能确定圆弧,圆孤它就圆上的一个角度
- Center:圆心
- radius:圆的半径
- startAngle:起始角度
- endAngle:终点角度
- clockwise:Yes顺时针,No逆时针
- 注意:startAngle角度的位置是从圆的最右侧为0度.
CGPoint center = CGPointMake(150, 150);
CGFloat radius = 100;
CGFloat startA = 0;//圆的0度角在圆的最右侧,
CGFloat endA = -M_PI_2;
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startA endAngle:endA clockwise:NO];
[path fill];
5. Cocoa Touch提供了哪几种Core Animation过度类型?
- Cocoa Touch 提供了 4 种 Core Animation 过渡类型,分别为:
- 交叉淡化、
- 推挤、
- 显示
- 覆盖
6. 能否想编译后得到的类中增加实例变量?能否向运行时创建的类中添加实例变量?为什么?
- 不能向编译后得到的类中增加实例变量
- 因为编译后的类已经注册在 runtime 中,类结构体中 objc_ivar_list 实例变量的链表和instance_size实例变量的内存大小已经确定,
- 同时runtime 会调用 class_setIvarLayout 或 class_setWeakIvarLayout 来处理 strong weak 引用。所以不能向存在的类中添加实例变量
- 能向运行时创建的类中添加实例变量
- 运行时创建的类是可以添加实例变量,调用 class_addIvar 函数。但是得在调用 objc_allocateClassPair 之后,objc_registerClassPair 之前,
- 原因同上。
7. 谈下你对快速点击事件的处理?
- (void)todoSomething:(id)sender{
//在这里做按钮的想做的事情。
}
- (void)starButtonClicked:(id)sender{
//先将未到时间执行前的任务取消。
[[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(todoSomething:)object:sender];
[self performSelector:@selector(todoSomething:) withObject:sender afterDelay:0.2f];
}
8. 请写出你调试解决crash问题的思路及步骤?
- 1)把问题拆分成多个小问题,一步步检验,直到找到问题的根源点
- 2)程序运行后,查看log信息,找到错误的地方
- 3)在错误的地方设置断点进行调试,可以加条件断点
- 4)查看断点运行的信息,进行修改
- 5) 如果是在测试阶段报错的话,可以在(设置-通用-关于本机-诊断与用量)里面看到崩溃的堆栈信息。
- 6)如果用rac的话,访问到已经释放了的内存,和内存警告这2种出错几率要高些。
9. NSDictionary类使用了哪些数据结构和算法?
- NSDictionary 使用Hash表实现Key/Object存储;
- Hash表是一种访问速度很快的数据结构,前提是Hash函数设计合理,能够使数据在各个子节点均匀分布,这一点使用NSString对象可以保证,这是文档中的说明:
Classes such as NSString that are part of Foundation have a good hash function.
10. iOS和iPhone做了哪些设计来降低功耗,延长续航时间?作为应用的开发者,又如何避免费电?
- iOS的省电机制主要有以下几种:
- 强化的后台机制
- 墓碑式:伪多任务,应用推至后台后,虽然没有被关闭,但是所有活动都被冻结,只能通过苹果服务器转发的推送来与用户交互
- 智能调度后台:在一些指定类别的APP,比如社交、新闻类的应用中,iOS系统会根据应用启动频率、时间和当前网络和电量的状况来智能分配每个应用的后台数据获取频率和启动时长,开发者自己不能设置数据具体什么时候更新
- 真后台:苹果也提供一些有诸多限制的接口来保证真后台,只供特定应用行为调用,比如后台音频,定位,上传下载等。
- 作为开发者如何省电
- 首先当然优化代码,积极合理地使用runloop,多线程等技术。
- 其次是尽量少地调用一些费电的接口,比如频繁的定位,频繁的后台更新数据,如无必要,尽量不用。
- 强化的后台机制