iOS中NSThread(主线程,子线程)

#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
原文地址:https://www.cnblogs.com/wohaoxue/p/4817456.html