运行循环和自动释放池
(一)RunLoop:
(1)运行循环。让可以让程序一直运行并接收用户的收入。所有的事件监听都是Runloop负责。
消息机制头文件:#import <objc/message.h> ,里面有一个objc_msgSend方法,就是方法调用的消息机制。从IOS8开始,运行时方法变得很长,消息机制都是这么传递的。
(2)时钟定时器:(schedu调度)
运行循环默认只在主线程开启,子线程默认的运行循环是不工作的。所以才能让子线程完毕后,自动销毁。但是当子线程需要监听时候,需要启动子线程运行循环。
添加 这句话(run)是一个死循环。come here永远不执行。需要满足某一个条件时,停止运行循环。
用到一个CF的函数。
代码:
/** 运行循环默认只在主线程上运行 子线程上默认的运行循环是不工作的!所以才能够让子线程执行完毕后,自动销毁 运行循环:监听事件! */ - (void)startTimer { NSLog(@"%@", [NSThread currentThread]); // 定时器 - NSDefaultRunLoopMode // [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(fire) userInfo:nil repeats:YES]; NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(fire) userInfo:nil repeats:YES]; // 添加到运行循环 // NSDefaultRunLoopMode - 默认的,表示应用程序空闲,绝大多数的事件响应都在这个模式:时钟 // UITrackingRunLoopMode - 追踪,专门用在 UIScrollView 滚动! // NSRunLoopCommonModes - 常用的模式数组,默认包含以上两种模式 // 在实际开发中,不建议将时钟的运行循环模式修改为 NSRunLoopCommonModes,一旦有耗时操作,会影响流畅度! [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; // 记录当前的运行循环 _timerRunLoop = CFRunLoopGetCurrent(); // 启动当前线程的运行循环 - 是一个死循环! // run 一旦启动,很难停止! // [[NSRunLoop currentRunLoop] run]; CFRunLoopRun(); NSLog(@"come here"); } - (void)fire { // 模拟延时 No run loop processing occurs while the thread is blocked. // 线程休眠的时候,run loop 不响应任何事件,开发中不要使用 // [NSThread sleepForTimeInterval:1.0]; // for (int i = 0; i < 1000 * 1000; ++i) { // [NSString stringWithFormat:@"hello - %d", i]; // } static int num = 0; NSLog(@"%d %@", num++, [NSThread currentThread]); // 满足某一个条件时,停止运行循环 if (num == 3) { NSLog(@"88"); CFRunLoopStop(CFRunLoopGetCurrent()); } }
IOS里面所有的事件监听都是RunLoop。
(二)自动释放池
(1)按钮点击
@interface ViewController () @property (nonatomic, assign) UIButton *button; @property (nonatomic, assign) Person *person; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // 延迟释放的对象,出了作用域之后,会被添加到最近一次创建的自动释放池中! self.person = [Person personWithName:@"zhangsan"]; NSLog(@"%@", self.person.name); // 类方法 self.button = [UIButton buttonWithType:UIButtonTypeContactAdd]; self.button.center = self.view.center; [self.view addSubview:self.button]; // 向 runloop 注册监听,按钮点击,执行 viewController 对象的 click 方法 [self.button addTarget:self action:@selector(click) forControlEvents:UIControlEventTouchUpInside]; } - (void)click { NSLog(@"%s", __FUNCTION__);
如上,返回一个类的,这种类方法都是延迟释放的。苹果底层都是MRC,MRC就一个原则,誰申请誰释放。所以需要init autoreleasepool。用自动释放池。
(2)自动释放池