1._objc_msgForward函数是做什么的,直接调用它将会发生什么?
_objc_msgForward用于消息转发,当向一个对象发送消息,但是没有响应时,会调用这个方法尝试做消息转发。
直接调用不当会导致应用crash。一旦调用_objc_msgForward,
将跳过查找 IMP 的过程,直接触发“消息转发”,导致crash。
- runtime如何实现weak变量的自动置nil?
runtime会对注册的类进行布局,weak对象会放入一个hash表中,用weak对象指向的内存地址作为指针,
当对象的引用计数器为0时,会调用delloc方法,加入weak对象的内存地址为a,以a为key,在weak表中搜索。
找到所有以a为键的weak对象,从而置为nil.
3.能否向编译后得到的类中增加实例变量?能否向运行时创建的类中添加实例变量?为什么?
不能向编译后的类中增加实例变量,可以向运行时的类新增实例变量。
1.编译后的类已经注册在runtime中,实例链表和示例变量的内存大小已经确定,
同时也已经处理好实例变量的strong和weak的引用,所以不能新增。
2.运行时的类可以新增示例变量,调用 class_addIvar 函数。
4.runloop和线程有什么关系?
1.runloop是线程循环,处理app的事件和响应,一个线程对应一个runloop,
2.主线程的runloop是默认启动的,但是其他线程的runloop需要手动启动,
在app启动时会有一个main()函数,其中UIApplocationMain()函数会为组线程设置一个runloop对象。
使应用可以在无人操作的时候休息,需要让它干活的时候又能立马响应。
5.runloop的mode作用是什么?
runloop有五种运行模式,model主要是指定事件再循环中的优先级的。
1.NSDefaultRunLoopMode(kCFRunLoopDefaultMode):默认,空闲状态
2.UITrackingRunLoopMode:ScrollView滑动时
3.UIInitializationRunLoopMode:启动时
4.NSRunLoopCommonModes(kCFRunLoopCommonModes):Mode集合
6.NSTimer,在滑动页面上的列表时,timer会暂定回调,为什么?如何解决?
1.首先runloop只能运行在一种model下,如果更换model小停下重新启动,
在滚动过程中runloop的模式会进行切换。所以定时器会暂停。
2.可以在定义定时器时讲定时器云心给的model设置为NSRunLoopCommonModes解决。
7.objc使用什么机制管理对象内存?
通过 retainCount 的机制来决定对象是否需要释放。 每次 runloop 的时候,
都会检查对象的 retainCount,如果retainCount 为 0,
说明该对象没有地方需要继续使用了,可以释放掉了。
8.BAD_ACCESS在什么情况下出现?
访问了悬垂指针,比如对一个已经释放的对象执行了release、
访问已经释放对象的成员变量或者发消息。 死循环
9.如何实现autoreleasepool的?
1.objc_autoreleasepoolPush
2.objc_autoreleasepoolPop
3.objc_autorelease
对 autorelease 分别执行 push,和 pop 操作。销毁对象时执行release操作。
10.使用block时什么情况会发生引用循环,如何解决?
一个对象中强引用了block,在block中又强引用了该对象,就会循环引用。
解决方法是使用__weak或者__block修饰符修饰之后再在block使用
11.内存分配
栈区:栈区(stack) 由编译器自动分配并释放,存放函数的参数值,局部变量等。
栈是系统数据结构,对应线程/进程是唯一的。
优点是快速高效,缺点时有限制,数据不灵活。[先进后出]
堆区:堆区(heap) 由程序员分配和释放,如果程序员不释放,程序结束时,
可能会由操作系统回收 ,比如在ios 中 alloc 都是存放在堆中。
优点是灵活方便,数据适应面广泛,但是效率有一定降低。[顺序随意]
12.使用系统的某些block api(如UIView的block版本写动画时),是否也考虑引用循环问题?
系统的某些block api中,UIView的block版本写动画时不需要考虑,但也有一些api 需要考虑:
所谓“引用循环”是指双向的强引用,所以那些“单向的强引用”(block 强引用 self )没有问题.
[UIView animateWithDuration:duration animations:^{ [self.superview layoutIfNeeded]; }];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{ self.someProperty = xyz; }];
这些情况不需要考虑“引用循环”。
但如果你使用一些参数中可能含有 ivar 的系统 api ,
如 GCD 、NSNotificationCenter就要小心一点:比如GCD 内部如果引用了 self,
而且 GCD 的其他参数是 ivar,则要考虑到循环引用
检测代码中是否存在循环引用问题,可使用 Facebook 开源的一个检测工具 FBRetainCycleDetector
13.GCD的队列(dispatch_queue_t)分哪两种类型?
1.串行队列:
2.并行队列
14.如何用GCD同步若干个异步调用?(如根据若干个url异步加载多张图片,然后在都下载完成后合成一张整图)
1.dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
2.dispatch_group_t group = dispatch_group_create();
3.dispatch_group_async(group, queue, ^{ /*加载图片1 */ });
4.dispatch_group_async(group, queue, ^{ /*加载图片2 */ });
5.dispatch_group_async(group, queue, ^{ /*加载图片3 */ });
6.dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// 合并图片
});
15.dispatch_barrier_async的作用是什么?
在并行队列中,为了保持某些任务的顺序,需要等待一些任务完成后才能继续进行,
使用 barrier 来等待之前任务完成,避免数据竞争等问题。
dispatch_barrier_async 函数会等加到Concurrent Dispatch Queue并行队列中的操作全部执行完之后,
然后再执行 dispatch_barrier_async 函数追加的处理,等 dispatch_barrier_async
追加的处理执行结束之后,Concurrent Dispatch Queue才恢复之前的动作继续执行。
注意:使用 dispatch_barrier_async ,该函数只能搭配自定义并行队列
dispatch_queue_t 使用。不能使用: dispatch_get_global_queue ,
否则 dispatch_barrier_async 的作用会和 dispatch_async 的作用一模一样。
16.若一个类有实例变量 NSString *_foo ,调用setValue:forKey:时,可以以foo还是 _foo 作为key?
两者是相同的
17.KVC的keyPath中的集合运算符如何使用?
1. 必须用在集合对象上或普通对象的集合属性上
2. 简单集合运算符有@avg, @count , @max , @min ,@sum,
3. 格式 @"@sum.age"或 @"集合属性[.@max.age](mailto:.@max.age)"
18.XML 介绍
1.XML是一种可扩展标记语言,跟JSON一样,也是常用的一种用于交互的数据格式,一般也叫XML文档。
规范的XML文档最多只有1个根元素,其他元素都是根元素的子孙元素
XML的解析方式有2种:
DOM:一次性将整个XML文档加载进内存,比较适合解析小文件
SAX:从根元素开始,按顺序一个元素一个元素往下解析,比较适合解析大文件
2.IOS开发中XML的解析
2.1.在iOS中,解析XML的手段有很多:
2.1.1.苹果原生 NSXMLParser:SAX方式解析,使用简单
2.1.2.libxml2:纯C语言,默认包含在iOS SDK中,同时支持DOM和SAX方式解析
2.1.3.GDataXML:DOM方式解析,由Google开发,基于libxml2
XML解析方式的选择建议:大文件:NSXMLParser、libxml2,小文件:GDataXML
19.JSON介绍
JSON数据结构是轻量级的数据交换格式,采用完全独立于语言的文本格式,
被称为理想的数据交换语言,易于人阅读和便携,同时也易于及其解析何程,
由于JSON解析便捷、 快速,并且相同数据用JSON编辑所占的内存更小,
所以在iOS中我们我们使用JSON解析更加普遍。
JSON中的数据类型:字符串、数值、BOOL、对象、数组。
1.iOS 开发中的JSON解析:
1.1. NSJSONSerialization,官方提供的Json数据格式解析类,iOS5以后支持
1.2. JSONKit(第三方类库)
1.3. SBJson
1.4. TouchJson
其中NSJSONSerialization是效率最高的,但是使用起来有点复杂。
20.列举 cocoa中常见对几种多线程的实现,并谈谈多线程安全的几种解决办法及多线程安全怎么控制?
1.只在主线程刷新UI
2.防止资源抢夺,使用synchronized加锁保护
3.一步操作保证线程安全,尽量使用GCD
21.你用过 NSOperationQueue么?如果用过或者了解的话,你为什么要使用 NSOperationQueue,实现了什么?请描述它和 GCD的区别和类似的地方
1.GCD是C语言的API,NSOperationQueue是基于GCD的封装
2.GCD支持FIFO的队列,但是NSOperationQueue可以调整执行顺序,设置最大并发量
3.NSOperationQueue可以快捷设置Operation的依赖关系。
4.GCD的执行速度比NSOperationQueue快。
- 在异步线程中下载很多图片,如果失败了,该如何处理?请结合 RunLoop来谈谈解决方案.(提示:在异步线程中启动一个 RunLoop重新发送网络请求,下载图片)
1.重新下载图片
2.下载完成,利用runloop回到主线程刷新UI
23.HTTP协议
HTTP是超文本传输协议,HTTP必备的要素:请求行,请求头,请求体
响应也要有状态行,响应头,实体内容,
1.请求行:请求行包含请求方法(Method),请求统一资源标识符,HTTP版本号。
2.请求头:存放客户端想给服务端的附加信息。
3.真正需要发给服务端的数据,在使用POST-multipart上传请求中请求体就是
上传文件的二进制NSData类型数据;在GET请求中请求体为空;
在普通的POST请求中请求体就是一些表单数据。在iOS中一般用`NSURLRequest`
与`NSMutableURLRequest`的`HTTPBody`属性
表示,添加body用[NSMutableURLRequest setHTTPBody:]`。
1.响应状态行:状态行是服务端返回给客户端的状态信息,包含HTTP版本号、状态码、状态码对应的英文名称。
2.这部分与请求部分差异不大,响应头的字field会稍许不同,响应头中的header field请求头响应头列表。
网友评论