iOS面经

作者: 咸鱼有只喵 | 来源:发表于2019-03-05 15:24 被阅读0次

1.HTTP和HTTPS

HTTPS:是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层,

区别

HTTP端口80,HTTPS端口443

HTTP是无状态的,HTTPS是可进行加密传输、身份认证的,更加安全

HTTPS需要CA证书,需要费用

工作原理

1.对称和非对称加密

对称:双方公用一个密钥 如AES

非对称:有一对密钥,公钥和私钥。公钥随便发,私钥则只能自己保管不会发出去,如果一旦用其中一个私钥加密,只能用另一个才能解开。如RSA、DSA

通话过程 

 客户端在使用HTTPS方式与Web服务器通信时有以下几个步骤,如图所示。

(1)客户使用https的URL访问Web服务器,要求与Web服务器建立SSL连接。

(2)Web服务器收到客户端请求后,会将网站的证书信息(证书中包含公钥)传送一份给客户端。

(3)客户端的浏览器与Web服务器开始协商SSL连接的安全等级,也就是信息加密的等级。

(4)客户端的浏览器根据双方同意的安全等级,建立会话密钥,然后利用网站的公钥将会话密钥加密,并传送给网站。

(5)Web服务器利用自己的私钥解密出会话密钥。

(6)Web服务器利用会话密钥加密与客户端之间的通信。

TCP三次握手四次挥手

网络概述https://www.jianshu.com/p/b4250ba3ef12

iOS响应链

1.当iOS程序中发生触摸事件后,系统会将事件加入到UIApplication管理的一个任务队列中

2.UIApplication将处于任务队列最前端的事件向下分发。即UIWindow。

3.UIWindow将事件向下分发,即UIView。

4.UIView首先看自己是否能处理事件,触摸点是否在自己身上。如果能,那么继续寻找子视图。

5.遍历子控件,重复以上两步。

6.如果没有找到,那么自己就是事件处理者。如果 7.如果自己不能处理,那么不做任何处理。

其中 UIView不接受事件处理的情况主要有以下三种 1)alpha <0.01

2)userInteractionEnabled = NO

3.hidden = YES.

2.扩大按钮的点击范围

用pointInside方法,在里面扩大bounds:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event {CGRectbounds =self.bounds;    bounds =CGRectInset(bounds,-10,-10);// CGRectContainsPoint判断点是否在矩形内returnCGRectContainsPoint(bounds, point);}

3.按钮的不规则点击区域

自定义Button,重写pointInside方法,

// //改变图片的点击范围- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event {//控件范围宽度多40,高度20CGRectbounds =CGRectInset(self.bounds,-20,-20);NSLog(@"point = %@",NSStringFromCGPoint(point));UIBezierPath*path1 = [UIBezierPathbezierPathWithRect:CGRectMake(-20,0,40,120)];UIBezierPath*path2 = [UIBezierPathbezierPathWithRect:CGRectMake(self.frame.size.width -20,0,40,120)];if(([path1 containsPoint:point] || [path2 containsPoint:point])&&CGRectContainsPoint(bounds, point)){//如果在path区域内,返回YESreturnYES;    }returnNO;}

4.hitTest是什么

事件传递的顺序和hittest 里面pointInside的执行顺序是反的, 比如现在有一个需求,一个按钮加在TabBar上,他的点击区域超过哟了tabbar如:

 如果此时点击超过的部分,按钮是不响应的,tabbar的ponintInside方法返回的是nil,也就是这个触摸点不在tabbar上,这时候我们需要重写tabbar的hitTest方法

//重写hitTest方法,去监听中间按钮的点击,目的是为了让凸出的部分点击也有反应- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event {//判断当前手指是否点击到中间按钮上,如果是,则响应按钮点击,其他则系统处理//首先判断当前View是否被隐藏了,隐藏了就不需要处理了if(self.isHidden ==NO) {//将当前tabbar的触摸点转换坐标系,转换到中间按钮的身上,生成一个新的点CGPointnewP = [selfconvertPoint:point toView:self.centerBtn];//判断如果这个新的点是在中间按钮身上,那么处理点击事件最合适的view就是中间按钮if( [self.centerBtn pointInside:newP withEvent:event]) {returnself.centerBtn;        }    }return[superhitTest:point withEvent:event];}

事件传递总结:

触摸事件的传递是从父控件传递到子控件

响应是相反的

多线程

1.NSThread 2.GCD 3.NSOPeration

第一种很少人会用 他是oc开线程的方法 因为有许多缺点 所以很少人会用(缺点:手动管理线程, 无法利用多核技术) 第二种 第三种 需要掌握 这里我们主要说说GCD 是如何开线程的 第三种NSOPeration 是对苹果公司 对GCD 的一个封装(掌握)

队列是一个存放任务的容器,而线程是执行这些任务的东西

@Propoety

一类是表示原子性(也就是线程安全)的,有atomic和nonatomic,默认是atomic,acomic也就是线程安全,但是我们一般都用的nonatomic,因为atomic的线程安全开销太大,影响性能,即使需要保证线程安全,我们也可以通过自己的代码控制,而不用atomic。

一类是表示引用计数的,有assign(iOS5以前用unsafe_unretained),strong,weak,copy。

assign: assign用于非指针变量,一般用于基础类型和C数据类型,这些类型不是对象,统一由系统栈进行内存管理。 weak:对对象的弱引用,不增加对象的引用计数,也不持有对象,当对象消失后指针自动指向nil,所以这里也就防止了野指针的存在。

strong:对对象的强引用,会增加对象的引用计数,如果指向了一个空对象,会造成野指针,平常我们用得最多的应该也是strong了。

copy:建立一个引用计数为1的新对象,赋值时对传入值进行一份拷贝,所以使用copy关键字的时候,你将一个对象复制给该属性,该属性并不会持有那个对象,而是会创建一个新对象,并将那个对象的值拷贝给它。而使用copy关键字的对象必须要实现NSCopying协议。

unsafe_unretained:跟 weak 类似,声明一个弱引用,但是当引用计数为 0 时,变量不会自动设置为 nil,现在基本都用weak了。 一类是表示读写权限的,默认是readwrite(可读可写),还有就是readonly,当你希望暴露出来的属性不能被外界修改时就需要申明为readonly。

在这里要重点说一下,使用NSMutableArray,NSMutableDictionary等可变集合对象的时候千万不要用copy,这里用copy 99%会出错,因为当你给该属性赋值时它会自动调用对象的copy方法,从而将可变集合转换成不可变集合,把一个不可变集合赋值给一个可变集合,就会造成错误。

/* 1.weak 1>OC对象2.assign 1>基本数据类型 2>OC对象3.strong 1>OC对象4.copy 1> NSString 2> block5.使用weak和assign修饰OC对象的区别 1>成员变量1) weak生成的成员变量是用__weak修饰的,比如Cat * __weak _cat; 2) assign生成的成员变量是用__unsafe_unretained修饰的Cat * __unsafe_unretained _cat; 2>__weak和__unsafe_unretained1)都不是强指针(不是强引用),不能保住对象的命2) __weak :所指向的对象销毁后,会自动变成nil指针(空指针),不再指向已经销毁的对象3) __unsafe_unretained :所指向的对象销毁后,仍旧指向已经销毁的对象*/---------------------

这样看来,在不可变对象之间进行转换,strong与copy作用是一样的,但是如果在不可变与可变之间进行操作,那么比较推荐copy,这也就是为什么很多地方用copy,而不是strong修饰NSString,NSArray等存在可变不可变之分的类对象了,避免出现意外的数据操作.

weak如何实现自动赋nil

Runtime 维护了一个 Weak 表,用于存储所有 Weak 指针。Weak 表是一个哈希表,Key 是对象的地址,Value 是一个数组,数组里面放的是 Weak 指针的地址(这个地址的值是所指对象的地址)。

简单来说,这个方法首先根据对象地址获取所有 Weak 指针地址的数组,然后遍历这个数组,把每个地址存储的数据设为 nil ,最后把这个 key-value entry 从 Weak 表中删除。

layoutIfNeeded和setNeedsLayout的区别

更新布局总会重新触发UIView的layoutSubviews方法。

layoutIfNeeded不一定会调用layoutSubviews方法。

setNeedsLayout一定会调用layoutSubviews方法(有延迟,在下一轮runloop结束前)。

使用 pod install 还是 pod update

你应该使用pod update PODNAME去只更新某个特定的库(检查是否有新版本,并尽可能更新到新的版本)。对应的,你应该使用pod install,这个命令不会更新那些已经安装了的库。

当你在你的Podfile里面添加了一个库的时候,你应该使用pod install,而不是pod update,这样既安装了这个库,也不需要去更新其它的已安装库。

你应该使用pod update去更新某个特定的库,或者所有的库(在Podfile的限制中)。

IsEqual和Hash

在OC中,==操作符对于对象类型只是比较对象地址,因为他和java一样不支持运算符重载,可以通过重写对象的isEqual方法来判断。

hash方法只在对象被添加至NSSet和设置为NSDictionary的key时会调用

hash方法主要是用于在Hash Table查询成员用的, 那么和我们要讨论的isEqual()有什么关系呢?

为了优化判等的效率, 基于hash的NSSet和NSDictionary在判断成员是否相等时, 会这样做

Step 1: 集成成员的hash值是否和目标hash值相等, 如果相同进入Step 2, 如果不等, 直接判断不相等

Step 2: hash值相同(即Step 1)的情况下, 再进行对象判等, 作为判等的结果

简单地说就是

hash值是对象判等的必要非充分条件

atomic 为什么不是线程安全的

变量定义和声明的区别

变量的声明有两种情况:

1、一种是需要建立存储空间的。例如:int a 在声明的时候就已经建立了存储空间。 告诉编译器,这个名字已经匹配到一块内存上,

2、另一种是不需要建立存储空间的。 例如:extern int a 其中变量a是在别的文件中定义的。

用static来声明一个变量的作用有二:

(1)对于局部变量用static声明,则是为该变量分配的空间在整个程序的执行期内都始终存在。

(2)外部变量用static来声明,则该变量的作用只限于本文件模块。

定义和声明的最重要区别就是:

定义创建对象并为这个对象分配了内存,声明没有分配内存。

+load 首先,load方法是一定会在runtime中被调用的,只要类被添加到runtime中了,就会调用load方法,所以我们可以自己实现laod方法来在这个时候执行一些行为。

而且有意思的一点是,load方法不会覆盖。也就是说,如果子类实现了load方法,那么会先调用父类的load方法,然后又去执行子类的load方法。同样的,如果分类实现了load方法,也会先执行主类的load方法,然后又会去执行分类的load方法。所以父类的load会执行很多次,这一点需要注意。而且执行顺序是 类 -> 子类 ->分类。而不同类之间的顺序不一定。

+initialize 与load不同的是,initialize方法不一定会执行。只有当一个类第一次被发送消息的时候会执行,注意是第一次。什么叫发送消息呢,就是执行类的一些方法的时候。也就是说这个方法是懒加载,没有用到这个类就不会调用,可以节省系统资源。

还有一点截然相反,却更符合我们预期的就是,initialize方法会覆盖。也就是说如果子类实现了initialize方法,就不会执行父类的了,直接执行子类本身的。如果分类实现了initialize方法,也不会再执行主类的。所以initialize方法的执行覆盖顺序是 分类 -> 子类 ->类。且只会有一个initialize方法被执行

objc中向一个nil对象发送消息将会发生什么?

是有效的只是在运行时不会有任何作用:

而给一个已经销毁的对象就会崩溃,因为 已经释放的对象,首先其内存可能已经被回收并且重新使用,这种情况下,你向其发送消息,实际上是给另外一个对象发送消息

oc 工厂模式

https://www.jianshu.com/p/847af218b1f

响应链

https://juejin.im/entry/58f5b7d0570c35005648a1ba

相关文章

  • iOS面经

    1.HTTP和HTTPS HTTPS:是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SS...

  • iOS面经

    高频问题:OOM: 监控可以用didReceiveMemoryWarning 也可以类似flex ,通过mallo...

  • 快手iOS面经

    原文作者:zhangferry 背景 过完年来北京之后,有准备看看机会,也是想了解下市场行情。简历没有投太多,只定...

  • 2020 iOS 面经

    从2020年七月份开始面试,陆续接触了 涂鸦、网易、哈啰、阿里好几个BU等等。最后也是顺利拿到了offer。 面经...

  • 快手iOS面经

    原文作者:zhangferry[https://juejin.im/post/684490410527031297...

  • 某某宝iOS面经

    1.首先是自我介绍,但还没介绍完他就开始提问了。2.然后谈项目,找几个点切入深究,会涉及到Apple的东西。主要是...

  • iOS基础通用面经

    通用必备基础知识 抛开iOS 开发这一项技能,我们最基础的本质还是一名软件开发工程师,所以基础的部分必不可少,本篇...

  • KS面试题答案-iOS

    题目引自 zhangferry — 快手iOS面经,此处根据自己理解做出解答记录 一面 1. 用递归写一个算法,计...

  • 2018 iOS 面经(仅供查看)

    本人是非985211学校,非计算机专业,技术一般,基础较差。 最开始秋招的时候,一线互联网基本上都投了,但是很多都...

  • ios面试资料

    比较系统的知识库,包含基础知识和ios oc面试知识点 iosBAT面经-有些小细节待自己搜索答案iOS面试题系列...

网友评论

      本文标题:iOS面经

      本文链接:https://www.haomeiwen.com/subject/vaqouqtx.html