zoukankan      html  css  js  c++  java
  • 多线程

    1. 主线程的生命周期和程序的生命周期一样.
    2. NSTimer不能在子线程上执行.
    3. 状态:创建->等待->运行->销毁->死亡.(另还有阻塞)

    NSRunLoop:主循环,可以控制任何线程。

    NSThread:自己管理状态,最复杂。

    Cocoa NSOperation:

    ----------------------------------------------------------------------------------------------------

    RootViewController.m

    #import "RootViewController.h"
    
    @interface RootViewController ()
    {
        int count;
        int ticketNumber;
        NSLock *lock;
    }
    @end
    
    @implementation RootViewController
    
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
    //    [self mA];
        
        count = 100;
        ticketNumber = 0;
        lock = [[NSLock alloc]init];
        
        NSThread *t1 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket) object:nil];
        t1.name = @"窗口1";
        [t1 start];
        
        NSThread *t2 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket) object:nil];
        t2.name = @"窗口2";
        [t2 start];
        
        NSThread *t3 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket) object:nil];
        t3.name = @"窗口3";
        [t3 start];
        
      
    }
    #pragma mark -NSThead的应用-
    -(void)saleTicket
    {
        while (1)
        {
            [lock lock];
            if (count > 0)
            {
                count = 100 - ticketNumber;
                NSLog(@"%@卖出第%d张票,剩余%d张票",[NSThread currentThread].name,ticketNumber,count);
                ticketNumber++;
            }
            else
            {
                [lock unlock];
                break;
            }
            [lock unlock];
        }
    }
    #pragma make -1-
    -(void)mA
    {
        
        //oc中线程创建
        /*
        //NSThread
        NSThread *t = [[NSThread alloc]initWithTarget:self
                                             selector:@selector(threadMethod)
                                               object:nil];
        [t start];
        */
        //    [self threadMethod];
        //2
    //    [NSThread detachNewThreadSelector:@selector(threadMethod) toTarget:self withObject:nil];
        /*
        //3
        NSOperation *operation = [[NSOperation alloc]init];
        [operation setCompletionBlock:^{
            for (int i = 0; i < 10; i++)
            {
                NSLog(@"新线程打印%d",i);
            }
        }];
        [operation start];
         */
        /*
        //4
        [self performSelectorInBackground:@selector(threadMethod) withObject:nil];
        //回到主线程
    //    [self performSelectorOnMainThread:<#(SEL)#> withObject:<#(id)#> waitUntilDone:<#(BOOL)#>];
        //在哪个线程上执行
    //    [self performSelector:<#(SEL)#> onThread:<#(NSThread *)#> withObject:<#(id)#> waitUntilDone:<#(BOOL)#>]
         */
        //5.比较常用
        NSOperationQueue *queue = [[NSOperationQueue alloc]init];
        //可设置并发数,第一次并发多少个,下一次
        queue.maxConcurrentOperationCount = 1;
    
        NSInvocationOperation *op = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(threadMethod) object:nil];
        //当CUP的资源不够时,可设置优先级,够的话,不影响优先级
        [op setQueuePriority:NSOperationQueuePriorityVeryLow];
        NSInvocationOperation *op2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(threadMethod2) object:nil];
        //当CUP的资源不够时,可设置优先级,够的话,不影响优先级
        [op2 setQueuePriority:NSOperationQueuePriorityVeryHigh];
        [queue addOperation:op];
        [queue addOperation:op2];
        //6.GCD
        
        [self mB];
        
    }
    -(void)mB
    {
        for (int i = 0; i < 10; i++)
        {
            NSLog(@"主线程打印%d",i);
        }
    }
    -(void)threadMethod
    {
        for (int i = 0; i < 10; i++)
        {
            NSLog(@"新线程打印%d",i);
        }
    }
    -(void)threadMethod2
    {
        for (int i = 0; i < 10; i++)
        {
            NSLog(@"新线程2打印%d",i);
        }
    }
    @end

     ---------------------------------------------------------------------------------------------

     

    2.ImageOperation.h(自定义请求图片的线程Operation)参考资料:http://c.gzl.name/archives/137

    /*自定义NSOperation*/
    @interface ImageOperation : NSOperation
    @property(nonatomic,assign)id target;
    @property(nonatomic,assign)SEL selector;
    @property(nonatomic,retain)NSString *imageURLString;
    
    -(id)initWithTarget:(id)target
              andAction:(SEL )selector
           andimageURLString:(NSString *)imageURLString;
    @end

    ImageOperation.m (走完初始化init方法之后自动会走main方法)

    #import "ImageOperation.h"
    
    @implementation ImageOperation
    -(id)initWithTarget:(id)target andAction:(SEL)selector andimageURLString:(NSString *)imageURLString
    {
        if (self = [super init])
        {
            self.target = target;
            self.selector = selector;
            self.imageURLString = imageURLString;
        }
        return self;
    }
    
    -(void)main
    {
        if ([self isCancelled])
        {
            return;
        }
        UIImage *image = [UIImage imageWithData:
                          [NSData dataWithContentsOfURL:
                           [NSURL URLWithString:self.imageURLString]]];

       [self.target performSelectorOnMainThread:self.selectorwithObject:image waitUntilDone:NO];//将image作参数传到self.selector方法中,image即self.target(作用绑定-initWithTarget:....)

        if ([self isCancelled])
        {
            return;
        }
    }
    @end

    RootViewController.h

    @interface RootViewController : UIViewController
    @property (weak, nonatomic) IBOutlet UIButton *GCDdownLoadBtn;
    
    @property (weak, nonatomic) IBOutlet UIButton *downloadBtn;
    @property (weak, nonatomic) IBOutlet UIImageView *headImageView;
    -(IBAction)downLoad:(id)sender;
    -(IBAction)GCDdownLoad:(id)sender;
    @end

    RootViewController.m

    #import "RootViewController.h"
    #import "ImageOperation.h"
    @implementation RootViewController
    
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    {
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        if (self) {
            // Custom initialization
        }
        return self;
    }
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
      
    }
    
    -(IBAction)downLoad:(id)sender
    {
        /*
        NSOperation *operation = [[NSOperation alloc]init];
        [operation setCompletionBlock:^{
            NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://pic.6188.com/upload_6188s/flashAll/s800/20120827/1346029443Rd9sjm.jpg"]];
            //ui要在主线程实现
            UIImage *image = [UIImage imageWithData:data];
            [self.headImageView performSelectorOnMainThread:@selector(setImage:) withObject:image  waitUntilDone:NO];
        } ];
        [operation start];
        */
        /*
        //2没有写blcok就需要放到队列里才会异步
        NSOperationQueue *queue = [[NSOperationQueue alloc]init];
        NSInvocationOperation *io = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(InvocationOperationDownload:) object:nil];
        [queue addOperation:io];
         */
        //3
       
        NSOperationQueue *queue = [[NSOperationQueue alloc]init];
        ImageOperation *imageOperation = [[ImageOperation alloc]initWithTarget:self andAction:@selector(refreshUI:)   andimageURLString:@"http://pic.6188.com/upload_6188s/flashAll/s800/20120827/1346029443Rd9sjm.jpg"];
        [queue addOperation:imageOperation];
        
    }
    #pragma mark -3-
    -(void)refreshUI:(UIImage *)image//因为self是image,所以这里的参数是UIImage
    {
        [self.headImageView performSelectorOnMainThread:@selector(setImage:)  withObject:image waitUntilDone:NO];//给imageView设置image
    }
    
    
    #pragma mark -2-
    -(void)InvocationOperationDownload:(NSInvocationOperation *)sender
    {
        NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://pic.6188.com/upload_6188s/flashAll/s800/20120827/1346029443Rd9sjm.jpg"]];
        //ui要在主线程实现
        UIImage *image = [UIImage imageWithData:data];
        [self.headImageView performSelectorOnMainThread:@selector(setImage:) withObject:image  waitUntilDone:NO];
    }
    #pragma mark -4-
    -(IBAction)GCDdownLoad:(id)sender
    {
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_async(queue, ^{
            NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://f.hiphotos.baidu.com/image/w%3D1366%3Bcrop%3D0%2C0%2C1366%2C768/sign=334e29095143fbf2c52ca2208648f1e3/f603918fa0ec08faa42f1fa65bee3d6d55fbda80.jpg"]];
            //ui要在主线程实现
            UIImage *image = [UIImage imageWithData:data];
            dispatch_async(dispatch_get_main_queue(), ^{
                self.headImageView.image = image;
            });
        });
    }
    @end

     ----------------------------------------------------------------------------------------------

    3.NSRunLoop

    RootViewController.m

    #import "RootViewController.h"
    
    @interface RootViewController ()
    {
        int count;
    }
    @end
    
    @implementation RootViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        /*如何提高NSTimer的准确性*/
        count = 0;
        NSOperationQueue *queue = [[NSOperationQueue alloc]init];
         NSInvocationOperation *op = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(threadMethod) object:nil];
        [queue addOperation:op];
    }
    -(void)threadMethod
    {
        @autoreleasepool
        {
            [NSTimer scheduledTimerWithTimeInterval:0.1
                                             target:self
                                           selector:@selector(print:)
                                           userInfo:nil
                                            repeats:YES];
        }
        /*NSRunLoop是线程相关基础框架的一部分,一个runLoop就是一个事件处理机制的循环,它可以不停的调度任务以及处理输入事件
         ,NSRunLoop可以保持一个线程处于活动状态,不会被销毁*/
        [[NSRunLoop currentRunLoop]run];//主线程也有一个runloop,测试?计时器放在多线程下可以提高准确性,游戏需要
        NSLog(@"runloop stop");
    }
    
    -(void)print:(NSTimer *)sender
    {
        if (count == 10)
        {
            [sender invalidate];
        }
        
        NSLog(@"hello world %d",count++);
        
    }
    @end

     4.

    CustomCell.h

    @interface CustomCell : UITableViewCell
    @property(nonatomic,retain)UIImageView *downImageView;
    @property(nonatomic,retain)NSString *imageViewUrlStr;
    -(void)loadImageWithQueue:(NSOperationQueue *)queue;
    @end

    Custom.m

    #import "CustomCell.h"
    
    @implementation CustomCell
    
    - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
    {
        self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
        if (self)
        {
            self.downImageView = [[[UIImageView alloc]initWithFrame:CGRectMake(10, 0, 100, 100)]autorelease];
            [self.contentView addSubview:self.downImageView];
        }
        return self;
    }
    -(void)setContentInCellWithModel:(NSString *)str
    {
    //    self.downImageView.image
    }
    -(void)loadImageWithQueue:(NSOperationQueue *)queue//将加载图片的线程加入外面的队列中
    {
        NSInvocationOperation *iop = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(downLoad) object:nil];
        [queue addOperation:iop];
        [iop release];
    }
    -(void)downLoad
    {
        UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:self.imageViewUrlStr]]];
        [self.downImageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];
    }
    -(void)down
    {
    //    [NSURLConnection connectionWithRequest:<#(NSURLRequest *)#> delegate:self];
    }
    @end

    RootViewController.h

    @interface RootViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>
    {
        NSMutableArray *dataSource;
        NSOperationQueue *queue;
    }
    @end

    RootViewController.m

    #import "RootViewController.h"
    #import "CustomCell.h"
    
    @implementation RootViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        dataSource = [[NSMutableArray alloc]initWithObjects:@"http://f.hiphotos.baidu.com/image/w%3D2048/sign=24dfaa86d2a20cf44690f9df42314a36/95eef01f3a292df59da38114be315c6034a8734a.jpg",
                      @"http://a.hiphotos.baidu.com/image/w%3D2048/sign=5c4c05ef8fb1cb133e693b13e96c574e/f9dcd100baa1cd111a6f1c20bb12c8fcc2ce2dd0.jpg",
                      @"http://b.hiphotos.baidu.com/image/w%3D2048/sign=0968c735347adab43dd01c43bfecb21c/503d269759ee3d6da48af3d641166d224f4ade5b.jpg",
                      @"http://a.hiphotos.baidu.com/image/w%3D2048/sign=8214ba3fbb12c8fcb4f3f1cdc83b9345/ac4bd11373f08202aa30592049fbfbedab641b0b.jpg",
                      @"http://c.hiphotos.baidu.com/image/w%3D2048/sign=4de426e7b68f8c54e3d3c22f0e112cf5/314e251f95cad1c845331c2e7d3e6709c93d512b.jpg",
                      @"http://d.hiphotos.baidu.com/image/w%3D2048/sign=d2714dddc2cec3fd8b3ea075e2b0d53f/72f082025aafa40f20987eccaa64034f78f01940.jpg",
                      @"http://c.hiphotos.baidu.com/image/w%3D2048/sign=3f69322892ef76c6d0d2fc2ba92efcfa/b03533fa828ba61e726728264334970a304e592a.jpg",
                      @"http://b.hiphotos.baidu.com/image/w%3D2048/sign=6a784b289113b07ebdbd570838ef9023/e61190ef76c6a7ef5f91642ffffaaf51f3de6600.jpg",
                      @"http://f.hiphotos.baidu.com/image/w%3D2048/sign=c8ff7f2271f082022d92963f7fc3faed/b21c8701a18b87d642cb301e050828381f30fd22.jpg",
                      @"http://e.hiphotos.baidu.com/image/w%3D2048/sign=48e859cae4cd7b89e96c3d833b1c43a7/a8773912b31bb05164f6ea28347adab44bede0e4.jpg", nil];
        
        //
        UITableView *tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, 320, 460) style:UITableViewStylePlain];
        [self.view addSubview:tableView];
        [tableView release];
        tableView.rowHeight = 100;
        tableView.delegate = self;
        tableView.dataSource = self;
        //
        queue = [[NSOperationQueue alloc]init];
        
    }
    
    
    #pragma mark - Table view data source
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return dataSource.count;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *CellIdentifier = @"Cell";
        CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        
        if (!cell)
        {
            cell = [[[CustomCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier]autorelease];
            
        }
        cell.imageViewUrlStr = [dataSource objectAtIndex:indexPath.row];
        [cell loadImageWithQueue:queue];
        return cell;
    }
    @end

    --------------------------------------------------------------------------------------------------------------------------------

    GCD中央回调,队列式结构:多核技术,性能最高

    • 不可变对象通常是线程安全的。一旦你创建它们,您可以安全地通过这些对象和线程。另一方面,可变的对象通常不是线程安全的。使用可变的对象在线程的应用程序中,应用程序必须适当地同步。

    1.线程问题:

    • 更新同一数据时,容易出现数据竞争,原因是并发而导致数据同时更新,线程不安全。该情况适合用同步,通常同一个文件、单独一个表、对同一个文件写东西就可以考虑用同步。
    • 同步的时候很容易出现死锁。
    • 开启多个线程会消耗大量内存。

    2.自定义线程:要管理内存

    串行队列:Serial Diapatch Queue.等待现在执行处理结束

    并行队列:Concurrent Dispatch Queue.不等待现在执行中处理结束

    3.系统线程:不用管理内存

    Main Diapatch Queue属于Serial Diapatch Queue类型

    Global Diapatch Queue属于Concurrent Dispatch Queue类型,有4个优先级

    Demo1---------------------------------------------------------自定义线程

    //1自定义线程创建
        dispatch_queue_t mySerialDispatchQueue = dispatch_queue_create("com.example.gcd.MySerialDispatchQueue", NULL);//第一个参数Serial Dispatch Queue的名称id.第二个参数NULL表示是Serial的,相反DISPATCH_QUEUE_CONCURRENT
        dispatch_release(mySerialDispatchQueue);
        dispatch_retain(mySerialDispatchQueue);
        //2自定义线程变更优先级方法
        dispatch_queue_t globalDispatchQueueBackground = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
        dispatch_set_target_queue(mySerialDispatchQueue, globalDispatchQueueBackground);

    Demo2---------------------------------------------------------线程组,并发执行

        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_group_t group = dispatch_group_create();
        
    
    
        dispatch_group_async(group, queue, ^
        {
            NSLog(@"one");
        });
        dispatch_group_async(group, queue, ^
        {
            NSLog(@"two");
        });
        dispatch_group_async(group, queue, ^
        {
            NSLog(@"three");
        });
        
        dispatch_group_notify(group, dispatch_get_main_queue(), ^
        {
            NSLog(@"done");
        });

     控制台输出结果:

    2014-07-18 05:18:11.351 MutThreadDemo[2999:3507] two
    2014-07-18 05:18:11.351 MutThreadDemo[2999:3803] three
    2014-07-18 05:18:11.350 MutThreadDemo[2999:1303] one
    2014-07-18 05:18:11.398 MutThreadDemo[2999:60b] done

    Demo3---------------------------------------------------------异步并行队列

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_async(queue, ^
        {
             NSLog(@"one");
        });
        dispatch_async(queue, ^
        {
            NSLog(@"two");
        });
        dispatch_async(queue, ^
        {
            NSLog(@"three");
        });
        dispatch_async(queue, ^
        {
            NSLog(@"four");
        });

    控制台结果:

    2014-07-18 05:16:28.091 MutThreadDemo[2977:3507] two
    2014-07-18 05:16:28.091 MutThreadDemo[2977:3803] three
    2014-07-18 05:16:28.091 MutThreadDemo[2977:1303] one
    2014-07-18 05:16:28.091 MutThreadDemo[2977:3903] four

     Demo4---------------------------------------------------------同步并行队列

        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_sync(queue, ^
        {
            NSLog(@"hello1");
        });
        dispatch_sync(queue, ^
        {
            NSLog(@"hello2");
        });
        dispatch_sync(queue, ^
        {
             NSLog(@"hello3");
        });
        dispatch_sync(queue, ^
        {
            NSLog(@"hello4");
                      });
        dispatch_sync(queue, ^
        {
            NSLog(@"hello5");
        });

    控制台输出结果:

    2014-07-18 05:36:24.841 MutThreadDemo[3214:60b] hello1
    2014-07-18 05:36:24.841 MutThreadDemo[3214:60b] hello2
    2014-07-18 05:36:24.842 MutThreadDemo[3214:60b] hello3
    2014-07-18 05:36:24.842 MutThreadDemo[3214:60b] hello4
    2014-07-18 05:36:24.843 MutThreadDemo[3214:60b] hello5

     Demo5---------------------------------------------------------并发处理数组类对象

     NSArray *array = [NSArray arrayWithObjects:@"0",@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9", nil];
    //并发处理数组类对象
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        
        dispatch_async(queue, ^
        {
            dispatch_apply([array count], queue, ^(size_t index)
            {
                NSLog(@"%zu: %@",index,[array objectAtIndex:index]);
            });
            dispatch_async(dispatch_get_main_queue(), ^
            {
                NSLog(@"done");
            });
        });

    打印结果:

    2014-07-18 06:00:08.645 MutThreadDemo[3456:3803] 1: 1
    2014-07-18 06:00:08.646 MutThreadDemo[3456:3a03] 3: 3
    2014-07-18 06:00:08.646 MutThreadDemo[3456:3903] 2: 2
    2014-07-18 06:00:08.645 MutThreadDemo[3456:1303] 0: 0
    2014-07-18 06:00:08.649 MutThreadDemo[3456:3a03] 5: 5
    2014-07-18 06:00:08.649 MutThreadDemo[3456:3803] 4: 4
    2014-07-18 06:00:08.649 MutThreadDemo[3456:3903] 6: 6
    2014-07-18 06:00:08.650 MutThreadDemo[3456:1303] 7: 7
    2014-07-18 06:00:08.653 MutThreadDemo[3456:3a03] 8: 8
    2014-07-18 06:00:08.654 MutThreadDemo[3456:3803] 9: 9
    2014-07-18 06:00:08.665 MutThreadDemo[3456:60b] done

     Demo6---------------------------------------------------------控制线程队列

        dispatch_suspend(queue);//挂起线程
        dispatch_resume(queue);//重新恢复线程

    Demo7----------------------------------------------------------并发串行队列

        //1自定义线程创建
        dispatch_queue_t mySerialDispatchQueue = dispatch_queue_create("com.example.gcd.MySerialDispatchQueue", NULL);//第一个参数Serial Dispatch Queue的名称id.第二个参数NULL表示是Serial的,相反DISPATCH_QUEUE_CONCURRENT
        dispatch_async(mySerialDispatchQueue, ^
        {
            NSLog(@"one");
        });
        dispatch_async(mySerialDispatchQueue, ^
        {
            NSLog(@"two");
        });
        dispatch_async(mySerialDispatchQueue, ^
        {
            NSLog(@"three");
        });
        dispatch_async(mySerialDispatchQueue, ^
        {
            NSLog(@"four");
        });

    控制台打印结果:

    2014-07-18 19:39:55.973 MutThreadDemo[486:1303] one
    2014-07-18 19:39:55.973 MutThreadDemo[486:1303] two
    2014-07-18 19:39:55.974 MutThreadDemo[486:1303] three
    2014-07-18 19:39:55.974 MutThreadDemo[486:1303] four

    Demo8---------------------------------------------------网络通信超时处理。因为GCD没有取消线程这个概念,只能用NSOperationQueue或者该处理方法。

        //发送请求的同时调回主线程开始计时
        dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
        //设置定时为15秒后,允许延迟1秒
        dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, 15ull * NSEC_PER_SEC), DISPATCH_TIME_FOREVER, 1ull * NSEC_PER_SEC);
        
        dispatch_source_set_event_handler(timer, ^
        {
            //执行。。。
        
    //执行完的后续处理。。。 dispatch_source_cancel(timer); }); dispatch_source_set_cancel_handler(timer, ^ { NSLog(@"释放资源"); // dispatch_release(timer); }); dispatch_resume(timer);//启动Dispatch Source定时

    Demo9------------------------------------某段时间后执行----------------------

    dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 3ull *NSEC_PER_SEC);//从现在时间开始,到3秒后.NSEC_PER_MSEC毫秒
        dispatch_after(time, dispatch_get_main_queue(), ^{
            NSLog(@"3秒后主线程执行");
        });

    Demo10------------------------------------信号量同步处理----------------------

    dispatch_semaphore_signal信号量+1

    dispatch_semaphore_wait信号量-1

    当信号量少于0的时候等待,大于等于0的时候,正常执行dispatch_semaphore_wait之后的内容

    //通过信号量将线程异步转化为线程同步
        dispatch_semaphore_t dispatchSemaphore = dispatch_semaphore_create(0);
        //
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_async(queue, ^{
            NSLog(@"线程1");
            //发送信号量
            dispatch_semaphore_signal(dispatchSemaphore);
        });
        dispatch_async(queue, ^{
            //等待信号量,当发送信号量执行完并且2秒后才执行下一句代码
            dispatch_semaphore_wait(dispatchSemaphore, dispatch_time(DISPATCH_TIME_NOW, 2.0f* NSEC_PER_SEC));
            NSLog(@"线程2");
        });

    .

    2015-07-13 15:16:14.727 SemaphoreTest[6945:518077] 线程1
    2015-07-13 15:16:14.727 SemaphoreTest[6945:518079] 线程2

    Demo11------------------------------------将异步的线程分开2部分----------------------

    dispatch_queue_t main = dispatch_get_main_queue();
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_group_t group = dispatch_group_create();
        dispatch_group_async(group, queue, ^{
             NSLog(@"线程1");
        });
        dispatch_group_async(group, queue, ^{
            NSLog(@"线程2");
        });
        dispatch_group_async(group, queue, ^{
            NSLog(@"线程3");
        });
    //    dispatch_group_notify(group, main, ^{
    //        NSLog(@"main");
    //    });
        //栅栏的作用
        dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
        NSLog(@"part1完成");
        group = dispatch_group_create();
        dispatch_group_async(group, queue, ^{
            NSLog(@"线程4");
        });
        dispatch_group_async(group, queue, ^{
            NSLog(@"线程5");
        });
        dispatch_group_async(group, queue, ^{
            NSLog(@"线程6");
        });

    .

    2015-07-13 15:07:49.903 SemaphoreTest[6789:511201] 线程3
    2015-07-13 15:07:49.903 SemaphoreTest[6789:511199] 线程2
    2015-07-13 15:07:49.903 SemaphoreTest[6789:511200] 线程1
    2015-07-13 15:07:49.904 SemaphoreTest[6789:511128] part1完成
    2015-07-13 15:07:49.905 SemaphoreTest[6789:511199] 线程5
    2015-07-13 15:07:49.905 SemaphoreTest[6789:511201] 线程6
    2015-07-13 15:07:49.904 SemaphoreTest[6789:511200] 线程4

     .

    dispatch_queue_t queue = dispatch_queue_create("my.concurrent.queue", DISPATCH_QUEUE_CONCURRENT);
        dispatch_async(queue, ^{
            NSLog(@"线程1");
            
        });
        dispatch_async(queue, ^{
            
            NSLog(@"线程2");
        });
        
        
        dispatch_async(queue, ^{
            NSLog(@"线程3");
            
        });
        dispatch_async(queue, ^{
            
            NSLog(@"线程4");
        });
        dispatch_barrier_async(queue, ^{NSLog(@"barrier");});
        dispatch_async(queue, ^{
            
            NSLog(@"线程5");
        });
        dispatch_async(queue, ^{
            
            NSLog(@"线程6");
        });
        dispatch_async(queue, ^{
            NSLog(@"线程7");
            
        });
        dispatch_async(queue, ^{
            
            NSLog(@"线程8");
        });

    .

    2015-07-13 15:22:53.511 SemaphoreTest[7067:524047] 线程3
    2015-07-13 15:22:53.511 SemaphoreTest[7067:524049] 线程1
    2015-07-13 15:22:53.511 SemaphoreTest[7067:524054] 线程4
    2015-07-13 15:22:53.511 SemaphoreTest[7067:524046] 线程2
    2015-07-13 15:22:53.512 SemaphoreTest[7067:524046] barrier
    2015-07-13 15:22:53.512 SemaphoreTest[7067:524046] 线程5
    2015-07-13 15:22:53.512 SemaphoreTest[7067:524054] 线程6
    2015-07-13 15:22:53.512 SemaphoreTest[7067:524046] 线程7
    2015-07-13 15:22:53.512 SemaphoreTest[7067:524054] 线程8

    usleep(100000); //程序挂起,等待0.1

    sleep(1);//程序挂起,等待1

    同步处理

    - (IBAction)start:(id)sender
    {
        self.pageStillLoading = YES;
        [NSThread detachNewThreadSelector:@selector(loadPageInBackground:)toTarget:self withObject:nil];
        [self.progressLabel setHidden:NO];
        while (self.pageStillLoading) {
            [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    //        sleep(1);
        }
        [self.progressLabel setHidden:YES];
    }
    
    - (void)loadPageInBackground:(id)sender
    {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            self.pageStillLoading = NO;
        });
    }

     

  • 相关阅读:
    ant-design-vue——子组件通过$parent修改父组件的值时无效问题及解决方法
    vue——quill-editor自定义图片上传
    ES6——var、let、const三者的区别
    js——数组/对象常用方法总结
    28.最长回文子序列
    27.马拉车
    26.扫雷一次点击
    JS添加内容之方法里传AJAX参数
    JQ 实现加载其他页面的H5代码 JQ加载H5独立导航栏代码
    CentOS 7不能上网 解决方法
  • 原文地址:https://www.cnblogs.com/huen/p/3625299.html
Copyright © 2011-2022 走看看