您的位置:首页 > 产品设计 > UI/UE

IOS--UI--LessonThread 线程

2015-07-30 20:58 344 查看
1.定义

/*

1.程序:由源代码生成的应用 简单的说 就是下载到手机或电脑上的 app;

2.进程:运行内存中的应用程序 比如 正在运行的 QQ 迅雷 前提是 必须是运行中的

3.线程:程序中 真正具有完成任务的一些子代码片段(一个程序必须至少有一个线程(主线程),为了完善我们的应用 在开发的时候我们会添加很多子线程)

注:开辟一个子线程会造成内存资源大量消耗,但是会提高用户体验;内存空间换时间

*/

2.主线程

//查看是哪个线程,并验证是否是主线程

NSLog(@"%@ ,%d",   [NSThread currentThread],[[NSThread currentThread] isMainThread]);




number =1;代表的是线程数字 name = main 就是主线程的意思;

我们可以写一个循环 然后运行

for (long i = 0; i < 10000000000000; i++) {
NSLog(@"放错位置了");//随便打印什么都可以
}


因为我们是直接在 APPdelegate 里面 所以 会先运行这个 for 循环 但是我们让他循环很多遍 模拟机就一直处于运行状态不能运行她的背景颜色

所以 当前任务在主线程中 未完成之前 其他任务都无法实现

问:如果我写个方法 在调用呢?

答:还是一样的 因为它都是在主线程中

为什么开辟子线程 ?对于耗时操作,如果有主线程来操作 会严重影响程序运行 和用户体验,这时为了用户体验 我们就把耗时操作放到子线程中去完成,主线程就可以做其他事情;

4.问 :如何开辟子线程

① 使用线程类 :NSThread

[NSThread detachNewThreadSelector:@selector(take) toTarget:self withObject :nil];

//实现方法
-(void)take{
//使用上面的方法后 现在当前任务已在子线程中 主线程就可以做自己的事情
for (long i = 0; i < 10000000000000; i++) {
NSLog(@"1放错位置了");
}
}
![number= 2 子线程](http://img.blog.csdn.net/20150730194107479)


②使用线程类: alloc 这种 需要手动开启线程

NSThread *thread =  [[NSThread alloc]initWithTarget:self selector:@selector(take2:) object:nil];
[thread start];
[thread release];

-(void)take2{
for (int i = 0; i < 1000; i ++) {
NSLog(@"变成猪");
}
}


③使用基类: NSObject

主线程跳转到子线程执行任务:直接创建子线程任务执行对应的耗时操作即可

子线程:子线程跳转到主线程执行任务,对于界面的刷新和用户交互由主线程操作

// [self performSelectorOnMainThread:@selector(refreshUI:) withObject:image waitUntilDone:YES]; 使用这个方法把子线程推回主线程

[self performSelectorInBackground:@selector(take3) withObject:nil];
UIImageView *imageV= [[UIImageView alloc]initWithFrame:[UIScreen mainScreen].bounds];
//下面要调用 可以选择用 tag值
imageV.tag = 100;
[self.window addSubview:imageV];
[imageV release];

-(void)take3{
//子线程中 系统不会帮我们生成自动释放池 这时候 如果我们使用遍历构造器对象 就会造成内存泄露
@autoreleasepool {
//将网址存入字符串中
NSString *urlString = @"http://image.zcool.com.cn/56/13/1308200901454.jpg";

//用数据源初始话对象
NSURL *url = [NSURL URLWithString:urlString];
//创造网络请求对象
NSURLRequest *request = [NSURLRequest requestWithURL:url ];

//与服务器建立连接

NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
//加载视图 将 data 转化为 image 对象
UIImage *image = [UIImage imageWithData:data];
//子线程完成耗时操作 主线程完成页面刷新 (对于 UI 界面的显示及用户的交互都要交给主线程完成,把子线程推回主线程)
//    第一个参数:推回主线程 选择的方法;如果方法里有参数就给个冒号 这个参数就是 withObject 后的内容 为 nil 就不用了
//    第二个参数:方法里需要的对象
//    第三个参数:是否等到之前操作完成
//        [self performSelectorOnMainThread:@selector(refreshUI:) withObject:image waitUntilDone:YES];
}

}

-(void)refreshUI:(UIImage *)image{

UIImageView *imageView = (UIImageView *)[self.window viewWithTag:100];
imageView.image = image;

}


④在主线程中开启一个定时器 可以定时执行任务

// 第一个参数:每隔多久走一次

// [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(take4) userInfo:nil repeats:YES];

// 创建子线程,创建定时器

// [self performSelectorInBackground:@selector(statimer) withObject:nil];

/④创建子线程对列: 任务对列

// 1.创建任务:1/ 2

NSInvocationOperation *op1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(take5) object:nil];
NSInvocationOperation *op2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(take6) object:nil];

[op1 release];
[op2 release];

-(void)take5{
for (int i =0; i < 10; i++) {
NSLog(@"Halo");
}

}
-(void)take6{
for (int i = 0; i <5; i ++) {
NSLog(@"ByeBye");
}

}
//    2.用 bocke 创建  就近就可以写任务 非常清晰 使用block 就不用释放了 没有 alloc
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
for (int i = 0; i <5; i ++) {
NSLog(@"ByeBye");
}

}];
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
for (int i = 0; i <5; i ++) {
NSLog(@"B你妹");
}

}];


5.创建对列

作用:队列中可以添加任务对象,形成任务对列 ,任务对列 为任务合理分配子线程完成任务

①多线程并发:多个任务在分配线程的适合遵循 FIFO 的原则 但是多个任务在分配玩线程之后同时执行任务,有可能最晚分配线程的任务最早执行完成;

// 举个栗子:排队等车(进入排队中之后你就要按着顺序去上车 遵循 FIFO)–>上车后同时前往目的地(这就是开辟线路同时出发)–>最先到达的不一定就是最先上车的人–>目的地;

NSOperationQueue *queue = [[NSOperationQueue alloc]init];

② 线程同步:多个任务之间存在依赖关系,具有先后顺序,后一个任务的执行必须等待前一个任务完成

//1.设置 并发执行最大数 这样就会按着顺序一个一个来

[queue setMaxConcurrentOperationCount:1];

// 2.任务之间存在依赖关系 所以添加依赖关系

[op2 addDependency:op1];

[queue addOperation:op1];

[op1 release];


[op2 release];

[queue release];

③ 线程互斥:当多个线程同时访问同一临界资源时,一个线程在访问,通过加锁方式 使其他线程处于等待状态;

线程锁死:临界资源加锁后,缺少解锁过程就会造成线程死锁,因为另一个线程还是在等待访问资源 没有解锁 就无法进入访问

给大家介绍一个很厉害的关于介绍线程的帖子 有点线程基础 再去看

/article/1318486.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: