将一个函数在主线程执行及子线程执行的方法

//开辟主线程

1.GCD方法,通过向主线程队列发送一个block块,使block里的方法可以在主线程中执行
dispatch_async(dispatch_get_main_queue( ),^{
//需要执行的方法
});

2.NSOperation方法
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];    //主队列
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
//需要执行的方法
}];
[mainQueue addOperation:operation];


3.NSThread方法
[self performSelector:@selector(method) onThread:[NSThread mainThread] withObject:nil waitUntilDone:YES modes:nil];

[self performSelectorOnMainThread:@selector(method) withObject:nil waitUntilDone:YES];

[[NSThread mainThread] performSelector:@selector(method) withObject:nil];

4.RunLoop方法
[[NSRunLoop mainRunLoop] performSelector:@selector(method) withObject:nil];


子线程
// 应用程序进程会默认开辟一个线程 -- 主线程 . 主线程的作用是更新 ui 界面 . 如果应用程序在运行过程中并不开辟其它线程 , 只有主线程可以完成任务操作 , 这种情形被称作单线程应用 . 单线程应用会出现一定程度的代码堵塞 , 导致用户界面假死
一,  GCD 的核心就是使用分发队列来管理任务的执行 , 分发队列分为两种 : 一种 serial( 串行 ), 一种 concurrent( 并发 ), 无论哪种队列都严格遵守 FIFO

    //1.<1> 获取 serial queue 的两种方式
    // 获取主线程队列 ,mainQueue 会在主线程中执行 . : 主线程会执行 mainQueue 中的各个任务
    dispatch_queue_t mainQueue = dispatch_get_main_queue ();
   
   
// 为主线程队列提交任务 , 任务以 block 形式提交
   
dispatch_async (mainQueue, ^{
       
NSLog ( @" 第一个任务 " );
    });
   
dispatch_async (mainQueue, ^{
       
NSLog ( @" 第二个任务 " );
        [
self calculate ];
     });
// block 中写要被执行的代码片段 , 也可以是方法的调用
   
   
dispatch_sync (mainQueue, ^{
       
NSLog ( @" 第三个任务 " );
        [
self downloadImage ];
    });  //同步提交任务函数


 <2> 除了可以获取主队列这种串行队列 , 还可以根据需求自己创建串行队列
    dispatch_queue_t mySerialQueue = dispatch_queue_create ( "com.lanou3g.GCD.mySerialQueue" , DISPATCH_QUEUE_SERIAL );   // 第一个参数是给当前创建的队列起名 , 苹果官方推荐使用反向域名命名 , 第二个参数是指定当前创建的队列的类型 , 分为 Serial Concurrent 两种
   
   
// 自定义的串行队列在分发执行任务时开辟子线程来执行
   
   
dispatch_async (mySerialQueue, ^{
       
NSLog ( @"first mission:%@" ,[ NSThread isMainThread ] ? @" is main thread" : @"isn't main thread" );
    });
   
   
dispatch_async (mySerialQueue, ^{
       
NSLog ( @"second mission:%@" ,[ NSThread isMainThread ] ? @" is main thread" : @"isn't main thread" );
    });
   
   
dispatch_async (mySerialQueue, ^{
       
NSLog ( @"third mission:%@" ,[ NSThread isMainThread ] ? @" is main thread" : @"isn't main thread" );
    });


    //2. 获取并发队列也有两种方法
<1>
    dispatch_queue_t globalQueue = dispatch_get_global_queue ( DISPATCH_QUEUE_PRIORITY_HIGH , 0 );    // 第一参数是用来控制队列的优先级的 , 第二个参数是苹果预留的参数 , 未来才会使用 , 目前设置为 0
   
    #define DISPATCH_QUEUE_PRIORITY_HIGH 2
   #define DISPATCH_QUEUE_PRIORITY_DEFAULT
0
   #define DISPATCH_QUEUE_PRIORITY_LOW (-
2 )
    #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN
   
   
   
//globalQueue 作为并发队列 , 会开辟若干个子线程来并发执行多个提交的任务 ( 开始较晚的任务不一定最后结束 , 开始较早的任务也不一定最先完成 )
   
dispatch_async (globalQueue, ^{
       
NSLog ( @"fisrt mission:%@" ,[ NSThread isMainThread ] ? @"is main thread" : @"isn't main thread" );
        [
self calculate ];
    });
   
   
   
dispatch_async (globalQueue, ^{
       
NSLog ( @"second mission:%@" ,[ NSThread isMainThread ] ? @"is main thread" : @"isn't main thread" );
        [
self downloadImage ];
    });
   
   
   
    <2>自己创建并发队列
   
   
dispatch_queue_t myConcurrentQueue = dispatch_queue_create ( "com.lanou3g.GCD.myConcurrentQueue" , DISPATCH_QUEUE_CONCURRENT );
        dispatch_async (myConcurrentQueue, ^{
           
NSLog ( @"fisrt mission:%@" ,[ NSThread isMainThread ] ? @"is main thread" : @"isn't main thread" );
            [
self calculate ];
        });
   
   
       
dispatch_async (myConcurrentQueue, ^{
           
NSLog ( @"second mission:%@" ,[ NSThread isMainThread ] ? @"is main thread" : @"isn't main thread" );
            [
self downloadImage ];
        });

   
   
// 延时提交某个任务到分发队列中
   
dispatch_after ( dispatch_time ( DISPATCH_TIME_NOW , ( int64_t )( 3 * NSEC_PER_SEC )), dispatch_get_main_queue (), ^{
      
NSLog ( @" 延时三秒后执行的任务 " );
   });
   
   
// 延时执行任务可以在 mainQueue 中正常执行 , 在自定义的队列中执行就会出现问题
   
dispatch_after ( dispatch_time ( DISPATCH_TIME_NOW , ( int64_t )( 3 * NSEC_PER_SEC )), myConcurrentQueue, ^{
       
NSLog ( @" 延时三秒后执行的任务 " );
    });


// 创建一个任务组
    dispatch_group_t group = dispatch_group_create ();
   
dispatch_group_async (group, myConcurrentQueue, ^{
       
NSLog ( @" 任务一 " );
    });
   
   
dispatch_group_async (group, myConcurrentQueue, ^{
       
NSLog ( @" 任务二 " );
        [
self calculate ];
    });
   
   
dispatch_group_notify (group, myConcurrentQueue, ^{
       
NSLog ( @" 任务三 " );
    });


  // 为了保证数据访问时的安全性 , 可以使用 serial queue 来解决访问的安全性问题
   
//serial queue 缺陷 : 后面的任务必须等待前面的任务执行结束后再执行 , 降低数据读取的效率
   
// 如果只是读取数据 , 适合使用 concurret queue
   
   
dispatch_async (myConcurrentQueue, ^{
       
NSLog ( @" 读取数据任务一 " );
    });
   
dispatch_async (myConcurrentQueue, ^{
       
NSLog ( @" 读取数据任务二 " );
    });
   
dispatch_async (myConcurrentQueue, ^{
       
NSLog ( @" 读取数据任务三 " );
    });
   
   
dispatch_barrier_async (myConcurrentQueue, ^{
       
NSLog ( @" 写入数据任务 " );
        [
self calculate ];
    });
//barrier_async 会等待它之前被提交的任务并发执行完后 , 才开始执行 , 并且执行完成后才开始执行后来被提交的任务 , 像一道墙 , 隔开了之前和之后提交的任务 . 这样的操作可以既保证读写的安全性 , 也可以提高读写的效率
   
   
   
dispatch_async (myConcurrentQueue, ^{
       
NSLog ( @" 读取数据任务四 " );
    });
   
   
dispatch_async (myConcurrentQueue, ^{
       
NSLog ( @" 读取数据任务五 " );
    });
   
   
   
for ( int i = 0 ; i < 10 ; i++) {
       
static dispatch_once_t onceToken;
       
dispatch_once (&onceToken, ^{
           
NSLog ( @" 任务被执行一次 " );
        });
    }




//二.    创建 NSInvocationOperation 对象
    NSInvocationOperation *invoOperation = [[[ NSInvocationOperation alloc ] initWithTarget : self selector : @selector (calculate) object : nil ] autorelease ];
   
  
// [invoOperation start];
   
   
   
// 创建 NSBlockOperation 对象
   
NSBlockOperation *blockOperation = [ NSBlockOperation blockOperationWithBlock :^{
        [
self downloadImage ];
    }];
 
//  [blockOperation start];
   
   
   
// 创建操作队列 , 通过操作队列完成操作对象的执行
  
// NSOperationQueue *queue = [NSOperationQueue mainQueue]; // 创建主线程队列
   
   
   
NSOperationQueue *queue = [[[ NSOperationQueue alloc ] init ] autorelease ];    // 自己创建的操作队列在执行相关操作对象时 , 会根据需求开辟子线程取执行
    [queue
setMaxConcurrentOperationCount : 2 ]; // 设置最大并发数 , 最大并发数如果是 1, 则表示队列中的操作被顺序执行 , 只有某个操作完成后才继续执行下一个操作
   
    [blockOperation
setQueuePriority : NSOperationQueuePriorityVeryHigh ];
    [invoOperation
setQueuePriority : NSOperationQueuePriorityVeryLow ];
   
    [queue
addOperation :invoOperation];
    [queue
addOperation :blockOperation];
   


//三.   应用程序进程会默认开辟一个线程 -- 主线程 . 主线程的作用是更新 ui 界面 . 如果应用程序在运行过程中并不开辟其它线程 , 只有主线程可以完成任务操作 , 这种情形被称作单线程应用 . 单线程应用会出现一定程度的代码堵塞 , 导致用户界面假死
   
// 开辟子线程方法一 :
   
NSThread *aThread = [[[ NSThread alloc ] initWithTarget : self selector : @selector (calculate) object : nil ] autorelease ]; // 开辟新的子线程并附加对应的方法 , 等待被执行
  
    aThread.
name = @" 子线程一 " ;
   
   
// 为子线程对象发送 start 信息 , 开启线程 , 执行相关方法
    [aThread
start ];
 
   
   
// 开辟子线程方法二 :
    [
NSThread detachNewThreadSelector : @selector (calculate) toTarget : self withObject : nil ];
   
    [
NSThread detachNewThreadSelector : @selector (downloadImage) toTarget : self withObject : nil ];
   
    [ self . activityIndicator startAnimating];

你可能感兴趣的:(iOS)