1.iOS如何令自己所写的对象具有拷贝功能?
想让自己所写的对象具有拷贝功能,则需实现 NSCopying 协议。如果自定义的对象分为可变版本与不可变版本,那么就要同时实现 NSCopying 与 NSMutableCopying 协议。
- (id)copyWithZone:(NSZone *)zone;
- (id)mutableCopyWithZone:(NSZone *)zone;
2.谈谈你对多线程开发的理解?iOS中有几种实现多线程的方法?
好处:
- 使用多线程可以把程序中占据时间长的任务放到后台去处理,如图片,视频的下载;
- 发挥多核处理器的优势,并发执行让系统运行的更快,更流畅,用户体验更好;
坏处:
- 大量的线程降低代码的可读性;
- 更多的线程需要更多的内存空间;
- 当多个线程对同一个资源出现争夺的时候要注意线程安全的问题。
在iOS中其实目前有4套多线程方案,他们分别是:
- Pthreads
- NSThread
- GCD
- NSOperation & NSOperationQueue
3.HTTPS的加密原理
- 服务器端用非对称加密(RSA)生成公钥和私钥;
- 然后把公钥发给客户端, 服务器则保存私钥;
- 客户端拿到公钥后, 会生成一个密钥, 这个密钥就是将来客户端和服务器用来通信的钥匙;
- 然后客户端用公钥对密钥进行加密, 再发给服务器;
- 服务器拿到客户端发来的加密后的密钥后, 再使用私钥解密密钥, 到此双方都获得通信的钥匙;
4.UIView如何获取所在的UIViewController?
在iOS中UIResponder类是专门用来响应用户的操作处理各种事件的,包括触摸事件(Touch Events)、运动事件(Motion Events)、远程控制事件(Remote Control Events)。我们知道UIApplication、UIView、UIViewController这几个类是直接继承自UIResponder,所以这些类都可以响应事件。当然我们自定义的继承自UIView的View以及自定义的继承自UIViewController的控制器都可以响应事件。
- (UIViewController *)getControllerFromView:(UIView *)view
{
//遍历响应者链,返回第一个找到视图控制器
UIResponser *responser = view;
while ((responder = [responder nextResponder])){
if ([responder isKindOfClass: [UIViewController class]]){
return (UIViewController *)responder;
}
}
// 如果没有找到则返回nil
return nil;
}
5.使用atomic一定线程安全吗?为什么?
这个问题很少遇到,但是答案当然不是。
atomic在set方法里加了锁,防止了多线程一直去写这个property,造成难以预计的数值。但这也只是读写的锁定。跟线程安全其实还是差一些。
也就是要注意:atomic所说的线程安全只是保证了getter和setter存取方法的线程安全,并不能保证整个对象是线程安全的
6.iOS性能优化的方向有哪些?
CPU方向:
创建对象时,尽量用轻量的对象代替重量的对象。比如CALayer 比 UIView要轻量许多,不需要响应触摸事件的控件可以用CALayer来显示(CALayer控件只能在主线程创建和操作,避免通过Storyboard创建视图对象)。
尽量推迟对象的创建时间,并把对象的创建分散到多个任务中去。(如果对象可以复用,并且复用的代价比释放、创建新对象要小,那么这类对象应当尽量复用)
3.应尽量减少对UIView的与CALayer相关的属性修改。(比如frame、bounds、transform、center等)
- 尽量避免视图层次调整,以及视图添加和移除。
5.避免容器内持有大量对象同时销毁,如果对象可以放到后台去释放,难就挪到后台线程去。
6.尽量减少视图的布局计算,应当在后台提前计算好视图布局,并且对视图布局进行缓存。(参考第3点,不要多次、频繁的计算和调整视图的这些属性)
7.. 图像绘制尽量放到后台线程,因为CoreGraphic方法通常是线程安全的,图像显示时再回到主线程。
- 当你用UIImage 或 CGImageSource 的相关方法创建图片时,应当在后台线程先把图片绘制到 CGBitmapContext 中,从 Bitmap 直接创建图片。(目前常见的网络图片库都做了这个处理)