运行循环和自动释放池

(一)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)自动释放池

 

posted @ 2016-08-25 15:59  三更小新  阅读(145)  评论(0编辑  收藏  举报