#import "AppDelegate.h"
@interface AppDelegate ()
{
NSInteger _totalTickests;
}
@property (nonatomic, retain) NSLock *lock;
@end
@implementation AppDelegate
- (void)task1 {
NSLog(@"当前线程:%@,是否是主线程:%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
//当前任务在主线程中完成,未完成之前不会执行后面的代码
for (long i = 0; i <= 10000000; i++) {
NSLog(@"%ld",i);
}
}
- (void)task2 {
NSLog(@"当前线程:%@,是否是主线程:%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
//当前任务在主线程中完成,未完成之前不会执行后面的代码
for (long i = 0; i <= 100; i++) {
NSLog(@"我是啦啦啦");
}
}
- (void)task3{
NSLog(@"嘎嘎嘎嘎嘎");
}
- (void)task4{
NSLog(@"蓝欧4");
}
- (void)task5{
NSLog(@"iOS5");
}
/**
* 系统默认在主线程中开启事件循环,不断地监听用户交互事件,但在子线程中没有开启时事件循环. runloop
*/
- (void)startTime{
@autoreleasepool {
//开启定时器
[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(task3) userInfo:nil repeats:YES];
//在子线程中开启事件循环,正是有了事件循环,定时器才能够重复的执行任务.
[[NSRunLoop currentRunLoop] run];
}
}
/*
程序:安装在移动设备上得每个应用,都是一个程序
进程:正在运行的每一个应用程序就是一个进程,进程相当于一个任务.
线程:执行任务的单元片段叫做线程,也就是任务的真正执行者,只不过系统默认的把任务交给一个线程来做,则个线程就是主线程,为了提高用户体验,我们需要把耗时的操作交给子线程来做.
*/
//买票
- (void)sellTickets:(NSString *)name{
@autoreleasepool {
while(YES){
[self.lock lock];
if (_totalTickests > 0) {
//买票
_totalTickests--;
NSLog(@"%@卖得票,剩余票数%ld张",name, _totalTickests);
}else{
NSLog(@"%@卖完了",name);
break;
}
[self.lock unlock];
}
}
}
//线程死锁:临界资源减少解锁的过程,就容易造成死锁,一个线程等待另一个线程释放资源,但是,前一个线程缺少解锁过程,造成后一个线程一直处于等待状态
//线程互斥:当多个线程访问同一资源,一个线程访问,其他线程应该等待,此时需要加锁
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
//NSLog(@"当前线程:%@,是否是主线程:%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
//初始化票数
_totalTickests = 30;
//创建锁
self.lock = [[[NSLock alloc] init] autorelease];
//窗口1
[NSThread detachNewThreadSelector:@selector(sellTickets:) toTarget:self withObject:@"张好好"];
//窗口2
[NSThread detachNewThreadSelector:@selector(sellTickets:) toTarget:self withObject:@"金凤"];
//[self task1];
//对于耗时的操作,交由子线程来完成,主线程依旧可以来处理用户交互和界面的变化
//1.创建子线程第一种方式,使用线程类 NSThread
//[NSThread detachNewThreadSelector:@selector(task1) toTarget:self withObject:nil];
//2.创建子线程第二种方式,使用线程类,需要手动开启
// NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(task1) object:nil];
//
// [thread start]; //开启线程
//
// //释放
// [thread release];
//3.创建子线程第三种方式,使用NSObject 提供的方法
//[self performSelectorInBackground:@selector(downloadImage) withObject:nil];
//主线程定时器
//[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(task3) userInfo:nil repeats:YES];
//创建子线程,开启定时器
//[self performSelectorInBackground:@selector(startTime) withObject:nil];
// UIImageView *imageView = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds];
// imageView.tag = 100;
// imageView.backgroundColor = [UIColor cyanColor];
// [self.window addSubview:imageView] ;
// [imageView release];
//4.创建子线程第四种方式,创建爱你任务队列,任务对列会为队列中的任务,合理安排子线程来完成任务.
//创建任务1
//NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(task4) object:nil];
// NSInvocationOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(task5) object:nil];
//创建任务2
// NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
// for (int i = 0; i < 10; i++) {
// NSLog(@"Frank is ....");
// }
// }];
//
// NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
// for (int i = 0; i < 10; i++) {
// NSLog(@"你说啥..");
// }
// }];
//创建任务队列,将任务添加到任务队列中
//NSOperationQueue *quene = [[NSOperationQueue alloc] init];
// //1.实现线程同步第一种方式,设置最大的并发数
// [quene setMaxConcurrentOperationCount:1];
//2.实现线程同步的第二种方式,添加依赖关系
//[op2 addDependency:op1];
//[quene addOperation:op1];
//[quene addOperation:op2];
//释放
//[op1 release];
//[op2 release];
//[quene release];
self.window.backgroundColor = [UIColor redColor];
[self.window makeKeyAndVisible];
return YES;
}
/**
* 线程同步:
线程并发:任务与任务之间没有先后关系,先执行的线程,有可能是最后一个完成的任务.
*/
/**
主线程跳转到子线程执行任务: 直接创建子线程, 执行对应的耗时的任务即可
子线程跳转到主线程执行任务: 对于界面的刷新操作, 交由主线程操作, 使用performSelectorOnMainThread::: 操作
*/
//下载图片
- (void)downloadImage{
//子线程没有自动释放池,遍历构造器内部操作是autorelease来管理内存,因此需要自己添加自动释放池
@autoreleasepool {
[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(task3) userInfo:nil repeats:YES];
//Get请求,同步连接
//1.创建网址字符串对象
NSString *str = @"http://image.zcool.com.cn/56/13/1308200901454.jpg";
//2.创建NSURL对象
NSURL *url = [NSURL URLWithString:str];
//3.创建请求对象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//4.连接
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
UIImage *image = [UIImage imageWithData:data];
//如果要刷新UI(界面),修改界面,应该交由主线程处理
//子线程跳转到主线程中,执行任务
[self performSelectorOnMainThread:@selector(referenceUI:) withObject:image waitUntilDone:YES];
//waitUntilDone :是否等待完成
//如果多个参数,可以将多个参数放入字典或者数组中,withObject:给字典或者数组即可
}
}
- (void)referenceUI:(UIImage *)image{
UIImageView *imageView = (UIImageView *)[self.window viewWithTag:100];
imageView.image = image;
}
- (void)dealloc{
self.window = nil;
self.lock = nil;
[super dealloc];
}
@end