iOS中关于多线程的实现方案的介绍(一)

什么是进程

>  进程是指在系统中正在运行的一个应用程序

>  每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内

什么是线程

>  1个进程要想执行任务,必须得有线程(每1个进程至少要有1条线程)

>  线程是进程的基本执行单元,一个进程(程序)的所有任务都在线程中执行

什么是多线程

>  1个进程中可以开启多条线程,每条线程可以并发(同时)执行不同的任务

>  进程 à 车间,线程 à 车间工人

>  多线程技术可以提高程序的执行效率

多线程的原理啊

>  同一时间,CPU只能处理1条线程,只有1条线程在工作(执行)

>  多线程并发(同时)执行,其实是CPU快速地在多条线程之间调度(切换)

>  如果CPU调度线程的时间足够快,就造成了多线程并发执行的假象

多线程优缺点

优点:

>  能适当提高程序的执行效率

>  能适当提高资源利用率(CPU、内存利用率)

缺点:

>  开启线程需要占用一定的内存空间(默认情况下,主线程占用1M,子线程占用512KB),如果开启大量的线程,会占用大量的内存空间,降低程序的性能

>  线程越多,CPU在调度线程上的开销就越大

>  程序设计更加复杂:比如线程之间的通信、多线程的数据共享

关于主线程(iOS)

什么是主线程

>     一个iOS程序运行后,默认会开启1条线程,称为“主线程”或“UI线程”

主线程的作用

>     显示\刷新UI界面

>  处理UI事件(比如点击事件、滚动事件、拖拽事件等)

主线程的使用注意

>  别将比较耗时的操作放到主线程中

>  耗时操作会卡住主线程,严重影响UI的流畅度,给用户一种“卡”的坏体验

iOS开发中,用于多线程开发技术,主要由以下几种


技术方案


简介


语言


生命周期


使用频率


Pthread


ü   一套通用的多线程API

ü   适用于Unix\linux\window等系统

ü   可跨平台,可移植

ü   适用难度大


C


程序员管理


几乎不用


NSThread


ü   使用更加面向对象

ü   简单易用,可直接操作线程对象


OC


程序员管理


偶尔使用


GCD


ü   用于替代NSThread等线程技术

ü   充分利用设备的多核


C


自动管理


经常适用


NSOperation


ü   基于GCD(底层是GCD)

ü   比GCD多一些更简单使用的功能

ü   适用更加面向对象


OC


自动管理


经常适用

关于pthread

由于pthread几乎不用,所我将用几个简单的案例说明,直接上代码

 1 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
 2
 3     [self began];
 4 }
 5
 6
 7
 8 // iOS开发,一般C语言的框架.h文件没有注释
 9 // http://baike.baidu.com
10
11 // 使用pthread创建线程
12 - (void)began
13 {
14     // 声明一个线程变量
15     pthread_t threadId;
16
17     //传给在线程中运行的函数的参数
18     id str = @"hello";
19
20
21     pthread_create(&threadId, NULL, run, (__bridge void *)(str));
22 }
23 // 线程中运行的耗时函数
24 void *run(void *param)
25 {
26     NSString *str = (__bridge NSString *)(param);//接收穿件来的函数
27
28     // 耗时操作放在这里执行
29     for (int i = 0; i < 20000; i++) {
30         NSLog(@"%@----%@", [NSThread currentThread], str);
31     }
32     //[NSThread currentThread]:打印当前线程
33
34     return NULL;
35 }

四个参数的解释

1. 要开的线程的变量

2. 线程的属性

3. 要在这个子线程执行的函数(任务)

4. 这个函数(任务)需要传递的参数

关于NSThread

我也讲通过代码来介绍NSThread

首先是创建NSThread的三种方式

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    [self began1];

}

//创建线程方法1
- (void)begin1
{
    //实例化一个线程对象,这个方法有利于线程属性的应用
    NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(run:) object:@"hellow"];

    //此方法需要手动发个线程开始工作,启动线程,在新开的线程中执行run方法
    [thread start];
}

//创建线程方法2
- (void)begin2
{
    [NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:@"函数参数"];
}

//创建线程方法3
- (void)begin3
{
    [self performSelectorInBackground:@selector(run:) withObject:@"函数参数"];
}

// 耗时操作,子线程中进行的函数
- (void)run:(NSString *)str
{
    for (int i = 0; i < 10; i++) {
        NSLog(@"%@--%d", [NSThread currentThread], i);
    }
}

NSThread的属性

- (void)test4
{
    NSThread *threadA = [[NSThread alloc] initWithTarget:self selector:@selector(run:) object:@"hello"];
    //线程名字,在[NSTread currentThread]的打印中可以看到
    threadA.name = @"thraed A";

    // 线程优先级
    // 是一个浮点数,0.0~1.0。 默认值 0.5
    // 开发的时候,一般不去修改优先级的值。
    // 优先级,必须调用很多次的时候,才能体现出来。
    threadA.threadPriority = 0.1;

    // 开始工作
    [threadA start];

    NSThread *threadB = [[NSThread alloc] initWithTarget:self selector:@selector(run:) object:@"hello"];

    threadB.name = @"thraed B";

    // 线程优先级
    // 是一个浮点数,0.0~1.0。 默认值 0.5
    threadB.threadPriority = 1.0;

    // 开始工作
    [threadB start];
}

控制线程状态

  1.启动线程

  -(void)start;

  2.阻塞线程

  +(void)sleepUntilDate:(NSDate *)date;

  +(void)sleepForTimeInterval:(NSTimeInterval)ti;

  3.强制停止线程

  +(void)exit;

  注意:程序一旦进入停止(死亡)状态,就不能再启动任务.

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [self began];
}

- (void)began
{
    // 1. 新建一个线程
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];

    // 2. 放到可调度线程池,等待被调度。 这时候是就绪状态
    [thread start];
}

- (void)run
{
    //进来就阻塞(休息)几秒
    [NSThread sleepForTimeInterval:5.0];
    //指定休息到什么时候
    [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:5.0]];

    //休息玩进入耗时操作
    for (int i = 0; i < 20; i++) {
        //也可再满足某一条件后进入休息
        if (i == 10) {
            [NSThread sleepForTimeInterval:2.0];
        }
        //也可让他在某一条件下终止线程的执行
        if (i == 15) {
            [NSThread exit];
        }
        NSLog(@"%@---%d",[NSThread currentThread], i);
    }
    NSLog(@"线程结束");

}

多线程的安全隐患

  1.一块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源

  2.当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题

可通过互斥锁来解决安全隐患问题

  互斥锁的使用格式

    @synchronized(锁对象,一般为self){//需要锁住的代码块}

    注意:锁定一份代码只能用一把锁,用多把锁是无效的

互斥锁的有缺点

    优点:能有效防止因多线程抢夺资源造成的数据安全问题

    缺点:需要消耗大量的CPU资源

但是苹果公司不推荐使用互斥锁,因为性能太差了.

所以,苹果公司默认将所有程序的更新UI都在主线程进行,也就不会出现多个线程改变一个资源

而在主线程更新UI的好处有"

  1.只在主线程更新UI,就不会出现多个线程同时改变一个UI控件

  2.主线程的优先级最高,也就意味着UI的更新优先级高,会让用户感觉很流畅,提升客户体验;\.

关于原子atomic和非原子nonatomic属性

  atomic:原子属性,为setter方法加锁(默认就是atomic),线程安全的,需要消耗大量的资源

  nonatomic:非原子属性,不会为setter方法加锁,非线程安全,适合内存小的移动设备,iOS开发中基本用该属性.

时间: 2024-10-18 05:10:55

iOS中关于多线程的实现方案的介绍(一)的相关文章

OS X 和iOS 中的多线程技术(上)

OS X 和iOS 中的多线程技术(上) 本文梳理了OS X 和iOS 系统中提供的多线程技术.并且对这些技术的使用给出了一些实用的建议. 多线程的目的:通过并发执行提高 CPU 的使用效率,进而提供程序运行效率. 1.线程和进程 进程 什么是进程 进程是指在计算机系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行中其专用且受保护的内存空间内 比如同时打开 Xcode .Safari ,系统就会分别启动两个进程 通过活动监视器可以查看Mac系统中所开启的进程 线程 什么是线程 一

OS X 和iOS 中的多线程技术(下)

OS X 和iOS 中的多线程技术(下) 上篇文章中介绍了 pthread 和 NSThread 两种多线程的方式,本文将继续介绍 GCD 和 NSOperation 这两种方式.. 1.GCD 1.1 什么是GCD GCD 全称 Grand Central Dispatch,可译为"牛逼的中枢调度器" GCD 基于纯 C 语言,内部封装了强大的函数库 1.2 使用 GCD 有什么优势 GCD 是苹果公司为多核的并行运算提出的解决方案 GCD 会自动利用更多的CPU内核 (如 二核 ,

IOS中的多线程【二】— NSOperation和NSOperationQueue

NSOperationQueue是一套基于Objective-c语言的API. GCD与NSOperationQueue的优缺点: NSOperationQueue:比较安全 GCD:没有NSOperationQueue安全,但使用起来简单,快速,还提供了一些操控底层的方法.实际开发中还是以GCD为主. NSOperationQueue实现多线程流程 1.定义一个任务队列. 2.定义一个任务. 3.把任务添加到队列中.一旦任务被添加到队列中,任务会马上被调度执行. 任务队列(NSOperatio

iOS开发笔记--iOS中的多线程

摘要 本文主要介绍iOS开发中的三种多线程技术:NSThread, NSOperation/NSOperationQueue, GCD.以及在多线程编程中的注意点和小技巧. 多线程 NSThread NSOperation/NSOperationQueue GCD 目录[-] iOS中的多线程 iOS的三种多线程技术特点: GCD基本思想 队列: 操作: 不同队列中嵌套同步操作dispatch_sync的结果: 同步操作dispatch_sync的应用场景: GCD优点: GCD队列: NSOp

iOS中的多线程及GCD

多线程中的一些概念 //任务:代码段  方法  线程就是执行这些任务 //NSThread类 创建线程 执行线程 [NSThread isMainThread]//判断是否是主线程 #import "AppDelegate.h" @implementation AppDelegate -(void)dealloc { [_window release]; [super dealloc]; } - (BOOL)application:(UIApplication *)applicatio

ios中的多线程的用法总结

ios中的多线程的用法总结 1.进程的基本概念 (1)每一个进程都是一个应用程序,都有独立的内存空间,一般来说一个应用程序存在一个进程,但也有多个进程的情况 (2)同一个进程的线程共享内存中的内存和资源 2.多线程的基本概念 (1)每一个程序都有一个主线程,程序启动时创建(调用main来启动). (2)多线程技术表示,一个应用程序有多个线程,使用多线程能提供CPU的利用率,防止主线程被堵塞. (3)任何有可能堵塞主线程的任务不要在主线程执行(如:访问网络). (4)主线程的生命周期和应用程序绑定

iOS中的多线程

iOS中的多线程 首先来了解什么是多线程,进程和线程的区别. 进程: 正在进行中的程序被称为进程,负责程序运行的内存分配; 每一个进程都有自己独立的虚拟内存空间. 线程:(主线程最大占1M的栈区空间,每条子线程最大占512K的栈区空间) 线程是进程中一个独立的执行路径(控制单元); 一个进程中至少包含一条线程,即主线程; 可以将耗时的执行路径(如网络请求)放在其他线程中执行; 线程不能被杀掉,但是可以暂停/休眠一条线程. 创建线程的目的: 开启一条新的执行路径,运行指定的代码,与主线程中的代码实

iOS中几种数据持久化方案

概论 所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问之前保存的数据.在iOS开发中,有很多数据持久化的方案,接下来我将尝试着介绍一下5种方案: plist文件(属性列表) preference(偏好设置) NSKeyedArchiver(归档) SQLite 3 CoreData 沙盒 在介绍各种存储方法之前,有必要说明以下沙盒机制.iOS程序默认情况下只能访问程序自己的目录,这个目录被称为"沙盒". 1.结构 既然沙盒就是一个文件夹,那就看看里面有什么吧

iOS中几种数据持久化方案总结

概论 所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问之前保存的数据.在iOS开发中,有很多数据持久化的方案,接下来我将尝试着介绍一下5种方案: plist文件(属性列表) preference(偏好设置) NSKeyedArchiver(归档) SQLite 3 CoreData 沙盒 在介绍各种存储方法之前,有必要说明以下沙盒机制.iOS程序默认情况下只能访问程序自己的目录,这个目录被称为"沙盒". 1.结构 既然沙盒就是一个文件夹,那就看看里面有什么吧