zoukankan      html  css  js  c++  java
  • iOS学习笔记4线程 smallelephant_A

    一,创建线程

    主线程

        NSThread *current = [NSThread currentThread];

     或

        NSThread *main = [NSThread mainThread];

    子线程(三种方法)

        NSThread *thread= [[NSThread alloc]initWithTarget:self selector:@selector(run:) object:@"线程A"];

        NSThread *thread3 = [NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:@"创建完直接启动"];

        NSThread *thread3 = [self performSelectorInBackground:@selector(run:) withObject:@"隐式创建"];

    二,线程安全隐患

    以售票为例

    #import "ViewController.h"

    @interface ViewController ()

    @property (nonatomic,strong)NSThread *thread1;

    @property (nonatomic,strong)NSThread *thread2;

    @property (nonatomic,strong)NSThread *thread3;

    @property (nonatomic,assign)int leftTicketCount;

    @end

    @implementation ViewController

    - (void)viewDidLoad {

        [super viewDidLoad];

        

    //    默认有10张票

        

        self.leftTicketCount = 10;

        

        

        self.thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(sellTicket) object:nil];

        self.thread1.name = @"售票员1";

        

        self.thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(sellTicket) object:nil];

        self.thread2.name = @"售票员2";

        

        self.thread3 = [[NSThread alloc]initWithTarget:self selector:@selector(sellTicket) object:nil];

        self.thread3.name = @"售票员3";

        

        // Do any additional setup after loading the view, typically from a nib.

    }

    -(void)sellTicket

    {

        while (1) {

            int count = self.leftTicketCount;

            if (count>0) {

                [NSThread sleepForTimeInterval:0.2];

                self.leftTicketCount = count-1;

                

                NSThread *current = [NSThread currentThread];

                NSLog(@"%@--卖了一张票,还剩%d张票",current,self.leftTicketCount);

                

            }else{

            

                [NSThread exit];

            

            }

        }

    }

    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

    {

        [self.thread1 start];

            [self.thread2 start];

        [self.thread3 start];

    }

    - (void)didReceiveMemoryWarning {

        [super didReceiveMemoryWarning];

        // Dispose of any resources that can be recreated.

    }

    怎样解决 多个线程调用同一个对象

    用互斥锁 如下

    -(void)sellTicket

    {

        while (1) {

            

            

            @synchronized(self) {

                int count = self.leftTicketCount;

                if (count>0) {

                    [NSThread sleepForTimeInterval:0.2];

                    self.leftTicketCount = count-1;

                    

                    NSThread *current = [NSThread currentThread];

                    NSLog(@"%@--卖了一张票,还剩%d张票",current,self.leftTicketCount);

                    

                }else{

                    

                    [NSThread exit];

                    

                }

            }

            }

            

    }

    互斥锁的优缺点

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

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

     

    互斥锁的使用前提:多条线程抢夺同一块资源 

    相关专业术语:线程同步,多条线程按顺序地执行任务

    互斥锁,就是使用了线程同步技术

     

     

    三,原子性与非原子性

     

    OC在定义属性时有nonatomic和atomic两种选择

    atomic:原子属性,为setter方法加锁(默认就是atomic)

    nonatomic:非原子属性,不会为setter方法加锁

     

    atomic加锁原理

    @property (assign, atomic) int age;

    - (void)setAge:(int)age

    @synchronized(self) { 
    _age = age;
    }
    }

    原子和非原子属性的选择

    nonatomic和atomic对比

    atomic:线程安全,需要消耗大量的资源

    nonatomic:非线程安全,适合内存小的移动设备

     

    四,线程之间的通信

     

    线程之间需要用到通信,比如 下载一个图片,线程a需要等到线程b下载好之后再显示出来

    以下是例子

    //  ViewController.m

    //  线程间的通信

    //

    //  Created by 谢谦 on 16/2/16.

    //  Copyright © 2016年 杜苏南. All rights reserved.

    //

    #import "ViewController.h"

    @interface ViewController ()

    @property (nonatomic,weak)IBOutlet UIImageView *iconView;

    @end

    @implementation ViewController

    - (void)viewDidLoad {

        [super viewDidLoad];

        // Do any additional setup after loading the view, typically from a nib.

    }

    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

    {

        [self performSelectorInBackground:@selector(download) withObject:nil];

    }

    -(void)download

    {

        NSURL *url = [NSURL URLWithString:@"fdsf"];

        NSData *data = [NSData dataWithContentsOfFile:url];

        

        

        UIImage *image= [UIImage imageWithData:data];

        

        [self performSelectorOnMainThread:@selector(settingImage:) withObject:image waitUntilDone:NO];

        

    }

    -(void)settingImage:(UIImage *)image

    {

        self.iconView.image = image;

    }

    - (void)didReceiveMemoryWarning {

        [super didReceiveMemoryWarning];

        // Dispose of any resources that can be recreated.

    }

    @end

    对于   

        [self performSelectorOnMainThread:@selector(settingImage:) withObject:image waitUntilDone:NO];

     有另外两种方法

        [self.iconView performSelector:@selector(settingImage:) onThread:[NSThread mainThread] withObject:image waitUntilDone:NO ];

        [self.iconView performSelectorOnMainThread:@selector(settingImage:) withObject:image waitUntilDone:NO];

  • 相关阅读:
    80端口被NT kernel & System 占用pid 4的解决方法 80端口被占用
    Linux:linux输入输出重定向、管道命令grep/wc、linux进程管理ps、pstree、kill命令、linux防火墙命令firewall-cmd、防火墙开启关闭端口号
    Linux:Linu文件权限管理、文件权限修改chmod、修改属主属组chown、特殊权限SUID、SGID、Sticky、umask
    [Java]获取图片高和宽
    [Java]获取Window界面的标题栏的高度大小
    [算法 笔记]字符串表达式计算(简易版)
    [算法 笔记]大数相乘(续)
    [算法 笔记]2014年去哪儿网 开发笔试(续)第一题BUG修正
    [算法 笔记]堆排序(续)
    [算法 笔记]用小范围随机函数编写大范围随机函数
  • 原文地址:https://www.cnblogs.com/adodo/p/5193294.html
Copyright © 2011-2022 走看看