面试题

1.简述KVC和KVO,其中KVO实现原理?

KVC : 键值编码(Key-Value Coding),它是一种通过key值访问类属性的机制,而不是通过setter/getter方法访问。其中 KVC 原理:当调用- (void)setValue:(id)value forUndefinedKey:(NSString *)key时,KVC底层的执行机制如下:

首先搜索对应属性的setter方法

如果没有找到属性的setter方法,则会检查+ (BOOL)accessInstanceVariablesDirectly方法是否返回了YES(该方法默认返回YES),如果返回了YES, 则KVC机制会搜索类中是否存在该属性的成员变量,也就是_属性名,存在则对该成员变量赋值。搜索成员变量名的顺序是 _key,_isKey,key,isKey。

另外我们也可以通过重写+ (BOOL)accessInstanceVariablesDirectly方法返回NO,这个时候KVC机制就会调用 - (void)setValue:(id)value forUndefinedKey:(NSString *)key。

如果没有找到成员变量,调用 - (void)setValue:(id)value forUndefinedKey:(NSString *)key。

2.Block实现原理;堆上和栈上的数据如何同步?

block本质上也是一个oc对象,他内部也有一个isa指针。block是封装了函数调用以及函数调用环境的OC对象。结构体,在栈上的情况, Block中的指针只是指向栈上的__block变量, 而当Block/__block变量被copy到堆上以后, 堆上Block会持有堆上__block变量. 而堆上的Block再次被调用copy时, 只是Block的引用计数+1而已, 而__block变量如果被多个堆上Block持有也只涉及到引用记数的变化. 一旦Block/__block变量的引用计数为0, 就会自动从堆上释放内存.这里Block/__block变量在堆上的内存管理与Objective-C对象完全一致.

3.推送如何实现的?

1.由App向iOS设备发送一个注册通知,用户需要同意系统发送推送。

2.iOS应用向APNS远程推送服务器发送App的Bundle Id和设备的UDID。

3.APNS根据设备的UDID和App的Bundle Id生成deviceToken再发回给App。

4.App再将deviceToken发送给远程推送服务器(自己的服务器), 由服务器保存在数据库中。

5.当自己的服务器想发送推送时, 在远程推送服务器中输入要发送的消息并选择发给哪些用户的deviceToken,由远程推送服务器发送给APNS。

6.APNS根据deviceToken发送给对应的用户。

4.简述weak的实现原理;

weak 关键字的作用弱引用,所引用对象的计数器不会加一,并在引用对象被释放的时候自动被设置为 nil;

weak是有Runtime维护的weak表;3.weak释放为nil过程

weak被释放为nil,需要对对象整个释放过程了解,如下是对象释放的整体流程:

1、调用objc_release

2、因为对象的引用计数为0,所以执行dealloc

3、在dealloc中,调用了_objc_rootDealloc函数

4、在_objc_rootDealloc中,调用了object_dispose函数

5、调用objc_destructInstance

6、最后调用objc_clear_deallocating。

对象准备释放时,调用clearDeallocating函数。clearDeallocating函数首先根据对象地址获取所有weak指针地址的数组,然后遍历这个数组把其中的数据设为nil,最后把这个entry从weak表中删除,最后清理对象的记录。

其实Weak表是一个hash(哈希)表,然后里面的key是指向对象的地址,Value是Weak指针的地址的数组

总结

weak是Runtime维护了一个hash(哈希)表,用于存储指向某个对象的所有weak指针。weak表其实是一个hash(哈希)表,Key是所指对象的地址,Value是weak指针的地址(这个地址的值是所指对象指针的地址)数组。

5. TCP 和 UDP 的区别

TCP 为传输控制层协议。这种协议提供面向连接的、可靠的、点到点的通信;

UDP 为用户数据报协议。这种协议提供非连接的、不可靠的、点到多的通信但是比 TCP 快。

6. TCP 的三次握手

第一次握手:客户端发送 syn 包(syn=j)到服务器,并进入 SYN_SEND 状态 ,等待服务器确认;

第二次握手:服务器收到 syn 包,必须确认客户的 SYN(ack=j+1),同时自己也发送一个 syn 包(syn=k),即 SYN+ACK 包,此时服务器进入 SYN+RECV 状态;

第三次握手:客户端收到服务器的 SYN+ACK 包,向服务器发送确认包 ACK(ack=k+1),此时发送完毕,客户端和服务端进入 ESTABLISHED 状态,完成三次握手

7. 属性readwrite,readonly,assign,retain,copy,nonatomic 各是什么作用,在那种情况下用

(1) readwrite 是可读可写特性;需要生成getter方法和setter方法时

(2) readonly 是只读特性 只会生成getter方法 不会生成setter方法 ;不希望属性在类外改变

(3) assign 是赋值特性,setter方法将传入参数赋值给实例变量;仅设置变量时;

(4) retain 表示持有特性,setter方法将传入参数先保留,再赋值,传入参数的retaincount会+1;

(5) copy 表示赋值特性,setter方法将传入对象复制一份;需要完全一份新的变量时。

(6) nonatomic 非原子操作,决定编译器生成的setter getter是否是原子操作,atomic表示多线程安全,一般使用nonatomic

8. @property 的本质是什么,ivar、getter、setter 是如何生成并添加到这个类中的

在普通 OC 对象中,@property 就是编译器自动帮我们生成一个成员变量(ivar)和它的 setter 和 getter 方法,它大概生成了五个东西:

1. objc_ivar_$类名$属性名称 该属性的偏移量

2. setter 与 getter 方法对应的实现函数

3. ivar_list 成员变量列表

4. method_list 方法列表

5. prop_list 属性列表

也就是说我们每次增加一个属性,系统就会在成员变量列表中添加一个成员变量的描述,在方法列表中添加 setter 与 getter 方法的描述,在属性列表中增加一个属性描述,然后计算该属性在对象中的偏移量,然后生成 setter 与 getter 方法对应的实现,在 setter 方法中从偏移量开始复制,在 getter 中从偏移量开始取值,为了能够读取正确的自己数,系统对对象偏移量的指针类型进行了类型强转。

9. @synthesize 和 @dynamic 分别有什么作用

@property 有两个对应的词,一个是 @synthesize,一个是 @dynamic。如果 @synthesize 和 @dynamic 都没写,那么默认的就是 @syntheszie var = _var;

@synthesize 的语义是如果你没有手动实现 setter 方法和 getter 方法,那么编译器会自动为你加上这两个方法。

@dynamic 告诉编译器,属性的 setter 与 getter 方法由用户自己实现,不自动生成。(当然对于 readonly 的属性只需提供 getter 即可)。假如一个属性被声明为 @dynamic var,然后你没有提供 @setter 方法和 @getter 方法,编译的时候没问题,但是当程序运行到 instance.var =someVar,由于缺 setter 方法会导致程序崩溃;或者当运行到 someVar = var时,由于缺 getter 方法同样会导致崩溃。编译时没问题,运行时才执行相应的方法,这就是所谓的动态绑定。

10. get 与 post 的区别

get 是向服务器索取数据的一种请求,post 是向服务器提交数据的一种请求;

get 没有请求体,post 有请求体;

get 使用 url 或 cookie 传参,而 post 将数据放在 body 中;

get 请求的数据会暴露在地址栏中,而 post 不会,所以 post 比 get 更安全;

get 请求对 url 长度有限制,而 post 请求对 url 理论上没有限制,但实际上,各个服务器会规定对 post 提交数据大小进行限制。

11. 描述下 SDWebImage 里面给 UIImageView 加载图片的逻辑

SDWebImage 中为 UIImageView 提供了一个分类 UIImageView+WebCache.h。这个分类中有一个最常用的方法:sd_setImageWithURL:placeholderImage: 会在真实图片出来前先显示占位图片,当真实图片被加载出来后再替换占位图片。

加载过程大致如下:

首先会在 SDWebImageCache 中寻找图片是否有对应的缓存,它会以 url 作为数据索引先在内存中寻找是否有对应的缓存,如果缓存未找到就会利用通过 MD5 处理过的 key 来继续在磁盘中查询对应的数据,如果找到了,就会把磁盘中的数据加载到内存中,并将图片显示出来,如果在内存中和磁盘缓存中都没有找到,就会向远程服务器发送请求,开始下载图片,下载后的图片会加载到缓存中,并写入磁盘中。整个获取图片的过程都是在子线程中执行,获取到图片后回到主线程将图片显示出来。

原理:

从内存中找到图片,找到直接使用;

从沙盒中找,找到使用,缓存到内存中;

从网络上获取,使用,缓存到内存,缓存到沙盒。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 223,604评论 6 521
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 95,650评论 3 401
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 170,578评论 0 366
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 60,469评论 1 300
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 69,486评论 6 399
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 53,030评论 1 314
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,414评论 3 426
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,382评论 0 278
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,920评论 1 322
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,967评论 3 343
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,104评论 1 354
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,758评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,433评论 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,920评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,040评论 1 275
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,590评论 3 380
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,134评论 2 362