IOS学习笔记 -- 多线程

多线程
1.多线程的原理
  1>.同一时间,CPU只能处理1条线程,只有1条线程在工作(执行)
  2>.多线程并发(同时)执行,其实是CPU快速地在多条线程之间调度(切换)
  3>.如果CPU调度线程的时间足够快,就造成了多线程并发执行的假象
如果线程非常非常多,会发生:
  1>.CPU会在N多线程之间调度,CPU会累死,消耗大量的CPU资源
  2>.每条线程被调度执行的频次会降低(线程的执行效率降低)

2.多线程的优缺点
  1>.多线程的优点
    能适当提高程序的执行效率
    能适当提高资源利用率(CPU、内存利用率)
  2>.多线程的缺点
    开启线程需要占用一定的内存空间(默认情况下,主线程占用1M,子线程占用512KB),如果开启大量的线程,会占用大量的内存空间,降低程序的性能
    线程越多,CPU在调度线程上的开销就越大
    程序设计更加复杂:比如线程之间的通信、多线程的数据共享

3.主线程
  一个iOS程序运行后,默认会开启1条线程,称为“主线程”或“UI线程”
   1>.主线程的主要作用
  显示\刷新UI界面
  处理UI事件(比如点击事件、滚动事件、拖拽事件等)
  2>.主线程的使用注意
  别将比较耗时的操作放到主线程中
  耗时操作会卡住主线程,严重影响UI的流畅度,给用户一种“卡”的坏体验

4.NSThread
  1> 开线程的几种方式
    * 先创建,后启动
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
    [thread start];
    * 直接启动
    a>.[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];
    b>.[self performSelectorInBackground:@selector(run) withObject:nil];

  2> 其他用法
    NSThread *current = [NSThread currentThread]; // 获取当前线程
    + (NSThread *)mainThread; // 获得主线程
    + (void)exit; // 强制停止线程
    * 阻塞(暂停)线程
    + (void)sleepUntilDate:(NSDate *)date;
    + (void)sleepForTimeInterval:(NSTimeInterval)ti;

  3> 同步锁(互斥锁)
    1块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源,比如多个线程访问同一个对象、同一个变量、同一个文件,当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题
    同步锁的使用前提:多条线程抢夺同一块资源
    a>.同步锁使用格式
      @synchronized(锁对象) { // 需要锁定的代码 }
      注意:锁定1份代码只用1把锁,用多把锁是无效的
    b>.同步锁的优缺点
      优点:能有效防止因多线程抢夺资源造成的数据安全问题
      缺点:需要消耗大量的CPU资源
    c>.线程同步
      线程同步的意思是:多条线程按顺序地执行任务
      同步锁,就是使用了线程同步技术

  4> 线程间通信
    - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
    - (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;

2.GCD(重点)
  1> GCD的优势
    GCD是苹果公司为多核的并行运算提出的解决方案
    GCD会自动利用更多的CPU内核(比如双核、四核)
    GCD会自动管理线程的生命周期(创建线程、调度任务、销毁线程)
    程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码
  2> 队列的类型
    * 并发队列
    获得全局的并发队列: dispatch_get_global_queue

    * 串行队列
    a.自己创建: dispatch_queue_create
    b.主队列: dispatch_get_main_queue
    并发和串行决定了任务的执行方式
    并发:多个任务并发(同时)执行
    串行:一个任务执行完毕后,再执行下一个任务
  3> 执行任务的方法类型
    * 同步(sync)执行
    * 异步(async)执行
    同步和异步决定了要不要开启新的线程
    同步:在当前线程中执行任务,不具备开启新线程的能力
    异步:在新的线程中执行任务,具备开启新线程的能力

  4> 线程间通信
    dispatch_async(
      dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
      // 执行耗时的异步操作...
      dispatch_async(dispatch_get_main_queue(), ^{
        // 回到主线程,执行UI刷新操作
      });
    });

  5> 其他用法
    dispatch_once // 用于单例对象
    dispatch_after // 延迟加载
    dispatch_group_async\dispatch_group_notify // 队列组

3.NSOperation
  1> 基本使用
    a>.NSInvocationOperation : - (id)initWithTarget:(id)target selector:(SEL)sel object:(id)arg;
    b>.NSBlockOperation : + (id)blockOperationWithBlock:(void (^)(void))block;
      - (void)addExecutionBlock:(void (^)(void))block; // 添加操作
      只要NSBlockOperation封装的操作数 > 1,就会异步执行操作

  2> NSOperationQueue(重点)
    *添加操作到NSOperationQueue中
    - (void)addOperation:(NSOperation *)op;
    - (void)addOperationWithBlock:(void (^)(void))block;
    * 最大并发数设置
    - (NSInteger)maxConcurrentOperationCount;
    - (void)setMaxConcurrentOperationCount:(NSInteger)cnt;
    *取消队列的所有操作
    - (void)cancelAllOperations;
    提示:也可以调用NSOperation的- (void)cancel方法取消单个操作

    *暂停和恢复队列
    - (void)setSuspended:(BOOL)b; // YES代表暂停队列,NO代表恢复队列
    - (BOOL)isSuspended;

    * 设置依赖(面试题)
    [operationB addDependency:operationA]; // 操作B依赖于操作A

  3> 自定义Operation(了解基本流程)
    重写- (void)main方法,在里面实现想执行的任务
    重写- (void)main方法的注意点
    自己创建自动释放池(因为如果是异步操作,无法访问主线程的自动释放池)
    经常通过- (BOOL)isCancelled方法检测操作是否被取消,对取消做出响应

  4> 如何解决一张图片(一个url)重复下载的问题(面试题)
    使用字典或对象根据url保存下载的异步操作,判断这个异步操作是否存在,存在就不在创建

IOS学习笔记 -- 多线程,布布扣,bubuko.com

时间: 2024-08-24 04:05:46

IOS学习笔记 -- 多线程的相关文章

iOS学习笔记-精华整理

iOS学习笔记总结整理 一.内存管理情况 1- autorelease,当用户的代码在持续运行时,自动释放池是不会被销毁的,这段时间内用户可以安全地使用自动释放的对象.当用户的代码运行告一段 落,开始等待用户的操作,自动释放池就会被释放掉(调用dealloc),池中的对象都会收到一个release,有可能会因此被销毁. 2-成员属性:     readonly:不指定readonly,默认合成getter和setter方法.外界毫不关心的成员,则不要设置任何属性,这样封装能增加代码的独立性和安全

iOS: 学习笔记, 值与引用类型(译自: https://developer.apple.com/swift/blog/ Aug 15, 2014 Value and Reference Type

值和引用类型 Value and Reference Types 在Swift中,有两种数据类型. 一是"值类型"(value type), 它是每一个实例都保存有各自的数据,通常定义为struct, enum或tuple. 二是"引用类型"(reference types),它是多实例共享一份数据,这种类型通常定义为class. 在本文中,我们将展示值类型和引用类型各自的优点以及如何在二者之间选择. 它们有什么区别? 最基本的区别是 "值类型"

iOS: 学习笔记, 值与引用类型(译自: https://developer.apple.com/swift/blog/ Aug 15, 2014 Value and Reference Types)

值和引用类型 Value and Reference Types 在Swift中,有两种数据类型. 一是"值类型"(value type), 它是每一个实例都保存有各自的数据,通常定义为struct, enum或tuple. 二是"引用类型"(reference types),它是多实例共享一份数据,这种类型通常定义为class. 在本文中,我们将展示值类型和引用类型各自的优点以及如何在二者之间选择. 它们有什么区别? 最基本的区别是 "值类型"

iOS学习笔记之ARC内存管理

iOS学习笔记之ARC内存管理 写在前面 ARC(Automatic Reference Counting),自动引用计数,是iOS中采用的一种内存管理方式. 指针变量与对象所有权 指针变量暗含了对其所指向对象的所有权 当某个方法(或函数)有一个指向某个对象的局部变量时,可以称该方法(或函数)拥有该变量所指向的对象,如: int main(int argc, const char * argv[]) { @autoreleasepool { // insert code here... NSSt

iOS学习笔记(十六)——数据库操作(使用FMDB)

iOS中原生的SQLite API在使用上相当不友好,在使用时,非常不便.于是,就出现了一系列将SQLite API进行封装的库,例如FMDB.PlausibleDatabase.sqlitepersistentobjects等,FMDB (https://github.com/ccgus/fmdb) 是一款简洁.易用的封装库,这一篇文章简单介绍下FMDB的使用. 在FMDB下载文件后,工程中必须导入如下文件,并使用 libsqlite3.dylib 依赖包. FMDB同时兼容ARC和非ARC工

iOS学习笔记之UITableViewController&UITableView

iOS学习笔记之UITableViewController&UITableView 写在前面 上个月末到现在一直都在忙实验室的事情,与导师讨论之后,发现目前在实验室完成的工作还不足以写成毕业论文,因此需要继续思考新的算法.这是一件挺痛苦的事情,特别是在很难找到与自己研究方向相关的文献的时候.也许网格序列水印这个课题本身的研究意义就是有待考证的.尽管如此,还是要努力的思考下去.由于实验室的原因,iOS的学习进度明显受到影响,加之整理文档本身是一件耗费时间和精力的事情,因此才这么久没有写笔记了. M

iOS: 学习笔记, Swift操作符定义

Swift操作符可以自行定义, 只需要加上简单的标志符即可. @infix 中置运算. 如+,-,*,/运算 @prefix 前置运算. 如- @postfix 后置运算. a++, a-- @assignment 赋值运算. +=, -=, --a, ++a // // main.swift // SwiftBasic // // Created by yao_yu on 14-7-27. // Copyright (c) 2014年 yao_yu. All rights reserved.

IOS学习笔记 -- Modal和Quartz2D

一. Modal1.Modal的默认效果:新控制器从屏幕的最底部往上钻,直到盖住之前的控制器为止;Modal只是改变了View的现实,没有改变rootViewController 2.常用方法1>.以Modal的形式展示控制器- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion2>.关

iOS: 学习笔记, 添加一个带界面约束的控制器

1. 创建一个空iOS应用程序(Empty Application). 2. 添加加控制器类. 修改控制器类的viewDidLoad 1 - (void)viewDidLoad 2 { 3 [super viewDidLoad]; 4 //创建标题 5 UILabel *header = [[UILabel alloc] init]; 6 header.text = @"欢迎来到我的世界!"; 7 header.textAlignment = NSTextAlignmentCenter