ios 多线程

摘要:
无法接收参数//使用NSInvocationOperation*op=[[NSInvocationOperationalloc]initWithTarget:selfselector:@selectorobject:@“hello”]//[self.myQueueaddOperation:op]不够灵活;[[NSOperationQueuemainQueue]addOperation:op];线程的资源抢占:解决方案:add@synchronized生成DemoObj+allocWithZone:zone{staticDemoObj*instance;//dispatch_once是线程安全的,onceToken表示0staticdispatch_once_onceToken;//dispach_once宏可以确保块代码中的指令只运行一次dispatch_oce;returninstance;}写入错误。实例){///thread10x00A///thread 20x00B//Instance=[[self-alloc]init];//}////第一个线程返回的指针已更改//returninstance;return[[self-alloc]init];}创建NSThreadNSThread有两种直接方法:[NSThreaddetachNewThreadSelector:@selectortoTarget:selfwithObject:nil];并且NSThread*myThread=[[NSThreadalloc]initWithTarget:selfselector:@selectorobject:nil];[my威胁启动];这两种方法的区别在于,一旦调用了前一种方法,它将立即创建一个线程来执行任务。配置线程,例如设置堆栈大小和线程优先级。

转自: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: 是一样的。





免责声明:文章转载自《ios 多线程》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇css 布局ACE安装和配置下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

《Win32多线程程序设计》学习笔记 第10章 MFC 中的线程

如果要在MFC程序中产生一个线程,而该线程将调用MFC函数或者使用MFC的任何数据,那么你必须以AfxBeginThread()或者CWinThread::CreateThread()来产生这些线程,理由同C runtime library. 在MFC中启动一个worker线程 如果线程调用了GetMessage或者CreateWindow之类的函数,消息...

Java虚拟机:十八、Java对象大小、对象内存布局及锁状态变化

一个对象占多少字节? 关于对象的大小,对于C/C++来说,都是有sizeof函数可以直接获取的,但是Java似乎没有这样的方法。不过还好,在JDK1.5之后引入了Instrumentation类,这个类提供了计算对象内存占用量的方法。至于具体Instrumentation类怎么用就不说了,可以参看这篇文章如何精确地测量java对象的大小。 不过有一点不同的...

pthread_exit/pthread_kill之后局部对象之析构

一、多线程与析构函数这个是在C++编码中可能存在的一个问题,假设说一个线程执行了局部变量的构造函数之后,没有退出局部对象作用域之前,它主动退出线程(pthread_exit)或者被动退出线程(pthread_kill ed),那么这个局部变量的析构函数是否会执行?这个问题对于通常的程序来说影响并不大,但是对于某些依赖在析构函数中执行复杂的系统级对象操作来说...

Kafka:生产者

Kafka java客户端数据生产流程解析 ProducerRecord ProducerRecord 含义: 发送给Kafka Broker的key/value 值对 //ProducerRecord的成员变量 public class ProducerRecord<K, V> { private final String top...

Python多线程----线程池以及线程实现异步任务

Python多线程----线程池 需求:假设我们现在有一个多线程项目,每有一个用户连接进来,我们的服务器就会创建一个线程。而我们的服务器最多能够承载100个线程,再多就会崩溃。为了防止恶意用户伪装真实用户构建大量的访问来让我们的服务器崩溃,现在需要对线程数量进行限制,一共只有100个线程,并且当一个用户访问结束以后线程会自动归还,等待下一个用户访问。如果1...

Win32多线程编程(1) — 基础概念篇

  内核对象的基本概念 Windows系统是非开源的,它提供给我们的接口是用户模式的,即User-Mode API。当我们调用某个API时,需要从用户模式切换到内核模式的I/O System Services API。例如我们调用Kernel32.dll中的CreateFile创建文件,最终将执行ntdll.dll中的系统服务NtCreateFile...