zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Reverse Linked List(算法)
    Move Zeroes (算法)
    Majority Element (算法)
    apk资源文件解析异常导致无法发编译的几种情况及解决方案
    使用update包更新系统文件的过程
    听鬼哥说故事之安卓学习手册_研究过程记录(未完成...)
    ios arm64
    ios,新浪微博
    ios ,微信分享
    ios,qq分享
  • 原文地址:https://www.cnblogs.com/wohaoxue/p/4817456.html
Copyright © 2011-2022 走看看