问题
- 如何绘制一个三角形?
1.1 如何绘制大量三角形?
1.2 一定要重写drawRect吗?
1.3 如何刷新View界面?
1.4 Layer好在哪? - assign和weak的区别
- 线程和RunLoop的关系
3.1 一个autorealese对象在什么时刻释放?(比如在一个vc的viewDidLoad中创建) - NSTimer有什么需注意的以及和RunLoop的关系?
- NSString copy 和 NSString mutableCopy 的区别
- 线程加锁原理(信号量,临界区,自选锁)
- iOS7 - iOS9的区别
- GCD指向了野指针了怎么办
- 用HTTP传数据,丢包严重怎么办
- iOS中广播的种类
- app slying
- runtime如何实现weak变量的自动置nil?
- AFNetworking的内部实现原理?
- block循环引用了如何解决?
- 如何用GCD同步若干个异步调用?(如根据若干个url异步加载多张图片,然后在都下载完成后合成一张整图)
- UIKit的框架结构?
答案
3.线程和RunLoop的关系
总的说来,Run loop,正如其名,loop表示某种循环,和run放在一起就表示一直在运行着的循环。实际上,run loop和线程是紧密相连的,可以这样说run loop是为了线程而生,没有线程,它就没有存在的必要。Run loops是线程的基础架构部分, Cocoa 和 CoreFundation 都提供了 run loop 对象方便配置和管理线程的 run loop (以下都以 Cocoa 为例)。每个线程,包括程序的主线程( main thread )都有与之相应的 run loop 对象。
runloop 和线程的关系:
- 1.主线程的run loop默认是启动的。
iOS的应用程序里面,程序启动后会有一个如下的main()函数
int main(int argc, char * argv[]) {
@autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
重点是UIApplicationMain()函数,这个方法会为main thread设置一个NSRunLoop对象,这就解释了:为什么我们的应用可以在无人操作的时候休息,需要让它干活的时候又能立马响应。
2.对其它线程来说,run loop默认是没有启动的,如果你需要更多的线程交互则可以手动配置和启动,如果线程只是去执行一个长时间的已确定的任务则不需要。
3.在任何一个 Cocoa 程序的线程中,都可以通过以下代码来获取到当前线程的 run loop 。
NSRunLoop *runloop = [NSRunLoop currentRunLoop];
猜想runloop内部是如何实现的?
一般来讲,一个线程一次只能执行一个任务,执行完成后线程就会退出。如果我们需要一个机制,让线程能随时处理事件但并不退出,通常的代码逻辑 是这样的:
function loop() {
initialize();
do {
var message = get_next_message();
process_message(message);
} while (message != quit);
}
或使用伪代码来展示下:
// http://weibo.com/luohanchenyilong/ (微博@iOS程序犭袁)
// https://github.com/ChenYilong
int main(int argc, char * argv[]) {
//程序一直运行状态
while (AppIsRunning) {
//睡眠状态,等待唤醒事件
id whoWakesMe = SleepForWakingUp();
//得到唤醒事件
id event = GetEvent(whoWakesMe);
//开始处理事件
HandleEvent(event);
}
return 0;
}
根据苹果在文档里的说明,RunLoop 内部的逻辑大致如下:
(答案参考:《招聘一个靠谱的iOS》面试题参考答案(下)第28、29、30、31问)
(拓展学习:《Objective-C之run loop详解》《深入理解RunLoop》《CFRunLoop》)
3.1 一个autorealese对象在什么时刻释放?(比如在一个vc的viewDidLoad中创建)
分两种情况:手动干预释放时机、系统自动去释放。
手动干预释放时机–指定autoreleasepool 就是所谓的:当前作用域大括号结束时释放。
系统自动去释放–不手动指定autoreleasepool
Autorelease对象会在当前的 runloop 迭代结束时释放。