• ios 多线程


    转自:http://www.maxiaoguo.com/clothes/254.html

    多线程包含:GCD  NSOperation   NSOperation是在GCD语言的基础上开发的,GCD类C语言, NSOperation OC语法

    GCD:

    名词解释 

    并行
     dispatch_queue_t q = dispatch_queue_create("cn.itcast.gcddemo", DISPATCH_QUEUE_CONCURRENT);
     串行
     dispatch_queue_t q = dispatch_queue_create("cn.itcast.gcddemo", DISPATCH_QUEUE_SERIAL);
    全局队列
    dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
     异步任务
     dispatch_async(q, ^{
            NSLog(@"异步任务 %@1111111", [NSThread currentThread]);
      });
    同步任务
    dispatch_sync(q, ^{
        NSLog(@"同步任务 %@1111111", [NSThread currentThread]);
     });

    dispatch_queue_t q = dispatch_queue_create("cn.itcast.demoqueue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_sync(q, ^{
        NSLog(@"并行同步 %@", [NSThread currentThread]);
    });
    

    主队列:

    dispatch_queue_t q = dispatch_get_main_queue();
    
        dispatch_async(q, ^{
            NSLog(@"主队列异步 %@", [NSThread currentThread]);
        });
    easy发成死锁情况:

    串行队列开启同步任务后嵌套同步任务造成死锁

     串行队列开启异步任务后嵌套同步任务造成死锁

    主队列不能放同步任务


    NSOperation 中的 NSBlockOperation 

    使用方法:

    n定义操作并加入到队列
    self.myQueue = [[NSOperationQueue alloc] init];
    NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
        [self operationAction:@"BlockOperation"];
    }];
    n将操作加入到队列
    [self.myQueue addOperation:op];
    这种NSBlockOperation是默认的异步的并行队列
    设定dependency能够改成串行并列
     // 设定运行顺序, Dependency依赖,可能会开多个,但不会太多
        // 依赖关系是能够跨队列的!

    [op2 addDependency:op1]; [op3 addDependency:op2]; [op4 addDependency:op3]; // GCD是串行队列。异步任务。仅仅会开一个线程

    NSOperation 中的 NSInvocationOperation

      // 须要定义一个方法。可以接收一个參数
        // 是用起来不够灵活
        NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(demoOp:) object:@"hello op"];
    //    [self.myQueue addOperation:op];
        [[NSOperationQueue mainQueue] addOperation:op];

    线程的资源抢夺:

    解决方法: 加@synchronized


    生成单例DemoObj的单例

    + (id)allocWithZone:(struct _NSZone *)zone
    {
        static DemoObj *instance;
        
        // dispatch_once是线程安全的,onceToken默觉得0
        static dispatch_once_t onceToken;
        // dispatch_once宏能够保证块代码中的指令仅仅被运行一次
        dispatch_once(&onceToken, ^{
            // 在多线程环境下,永远仅仅会被运行一次,instance仅仅会被实例化一次
            instance = [super allocWithZone:zone];
        });
        
        return instance;
    }
    错误写法。原因:当多个线程同一时候运行的时候会生成多个instance

    + (instancetype)sharedDemoObj
    {
        // 假设有两个线程同一时候实例化,非常有可能创建出两个实例来
    //    if (!instance) {
    //        // thread 1 0x0000A
    //        // thread 2 0x0000B
    //        instance = [[self alloc] init];
    //    }
    //    // 第一个线程返回的指针已经被改动!

    // return instance; return [[self alloc] init]; }


    NSThread

    NSThread的创建主要有两种直接方式:

    [NSThread detachNewThreadSelector:@selector(myThreadMainMethod:) toTarget:self withObject:nil];
    和
    NSThread* myThread = [[NSThread alloc] initWithTarget:self
                                            selector:@selector(myThreadMainMethod:)
                                            object:nil];
    [myThread start];

    这两种方式的差别是:前一种一调用就会马上创建一个线程来做事情。而后一种尽管你 alloc 了也 init了,可是要直到我们手动调用 start 启动线程时才会真正去创建线程。这样的延迟实现思想在非常多跟资源相关的地方都实用到。后一种方式我们还能够在启动线程之前。对线程进行配置,比方设置 stack 大小,线程优先级。



    另一种间接的方式。更加方便,我们甚至不须要显式编写 NSThread 相关代码。那就是利用 NSObject 的类方法 performSelectorInBackground:withObject: 来创建一个线程:
    [myObj performSelectorInBackground:@selector(myThreadMainMethod) withObject:nil];
    其效果与 NSThread 的 detachNewThreadSelector:toTarget:withObject: 是一样的。





  • 相关阅读:
    Linux命令行和Shell脚本编程
    Excel自动触发时间
    dom4j读取xml文件 简单例子
    GSM & Foxit Reader
    ThreadPoolExecutor 线程池
    Linux /var/log
    delphi开发技巧
    利用ScktSrvr打造多功能Socket服务器
    delphi中Windows消息大全使用详解
    自己构造注入点方便入侵
  • 原文地址:https://www.cnblogs.com/yxysuanfa/p/7359151.html
Copyright © 2020-2023  润新知