巧妙借用通知机制 理解runLoop机制

来源:互联网 发布:程序员转正述职报告 编辑:程序博客网 时间:2024/04/27 16:58

        以前学习通知的时候,老师布置了这样一个作业:老师布置任务,需要学生学习10分钟,学习时间满10分钟后,通知老师,老师结束任务。显而易见,这题主要考察通知的用法。关于通知的用法不是本文的重点,so略过。神器来了,我定义两个类,Student(学生类)、Teacher(教师类)。以下是Student.h:

//  Created by Wu on 14-5-12.//  Copyright (c) 2014年 Wu. All rights reserved.//#import <Foundation/Foundation.h>#define Student_Notification   @"Student_Notification"  //宏定义 通知的名称@interface Student : NSObject{    NSInteger  _workTime;   //定义一个整型变量 用来表示学生的学习时间}@end
然后 ,Student.m:
#import "Student.h"@implementation Student- (id) init{    self = [super init];    if (self!=nil) {        _workTime = 0;        [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(timeAction:) userInfo:nil repeats:YES];    }    return self;}- (void)timeAction:(NSTimer*)timer{    _workTime += 2;    NSLog(@"学生学习的时间为:%ld",_workTime);    if (_workTime>=10) {        //当学习时间超过10分钟后通知老师        [[NSNotificationCenter defaultCenter] postNotificationName:Student_Notification object:[NSNumber numberWithInteger:_workTime] userInfo:nil];        [timer invalidate];    }}@end
看到这有没有发现什么?是的,在学生类的init方法中加了一个定时器,每隔1秒执行一下timeAction方法,让_workTime加2。 当_workTime大于10的时候,停止定时器,通知老师。

     然后,Teacher.h类的代码:程序猿就喜欢上代码,表嘲笑~~~

//  Created by Wu on 14-5-12.//  Copyright (c) 2014年 TCSL. All rights reserved.//#import <Foundation/Foundation.h>@interface Teacher : NSObject@end
是的,Teacher.h文件里面啥玩意都没有,够简洁吧~~下面是Teacher.m文件的内容:

#import "Teacher.h"#import "Student.h"@implementation Teacher- (instancetype) init{    self = [super init ];    if (self!=nil) {        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(teacherAction:) name:Student_Notification object:nil];    }    return self;}- (void)teacherAction:(NSNotification*)notification;{    NSNumber * number = notification.object;    NSLog(@"学生完成任务了,学习时间为:%d",[number intValue]);}@end

 

然后,在main.m文件中执行以下代码:

#import <Foundation/Foundation.h>#import "Teacher.h"#import "Student.h"int main(int argc, const char * argv[]){    @autoreleasepool {        Student * student = [[Student alloc] init];        Teacher * teacher = [[Teacher alloc] init];                NSLog(@"执行完成");            }    return 0;}
 大笑鸡冻人心的时刻来临了,look!:




  是的,什么都没有,定时器没有执行!!*****为什么没有执行呢??这下引到了本文的重点了,这是因为在执行 Student  * student =  [[ Student allco] init] 

方法的时候啊,runLoop没有执行,直接把定时器释放了。定时器与runLoop的关系见:http://www.kankanews.com/ICkengine/archives/40923.shtml。加上

 [[NSRunLoop currentRunLoop] run];  执行,出现了我们希望看到的结果。大笑大笑

  总结下:runLoop的使用场合:
1. 使用port或是自定义的input source来和其他线程进行通信
2. 在线程(非主线程)中使用timer
3. 使用 performSelector…系列(如performSelectorOnThread, …)
4. 使用线程执行周期性工作

 如果我们的线程中不启动runLoop的话,student执行init方法就立即结束了,线程释放了定时器还执行个pi啊!所以手动启用runLoop非常关键,以后得注意了哦!微笑好了,今天的blog就写到这里。


0 0
原创粉丝点击