iOS开发笔记4-线程

一,创建线程

主线程

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];

时间: 2024-08-27 09:43:01

iOS开发笔记4-线程的相关文章

iOS开发多线程篇—线程的状态

iOS开发多线程篇—线程的状态 一.简单介绍 线程的创建: self.thread=[[NSThread alloc]initWithTarget:self selector:@selector(test) object:nil]; 说明:创建线程有多种方式,这里不做过多的介绍. 线程的开启: [self.thread start]; 线程的运行和阻塞: (1)设置线程阻塞1,阻塞2秒 [NSThread sleepForTimeInterval:2.0]; (2)第二种设置线程阻塞2,以当前时

IOS开发笔记-百度地图(第三方库)

最近做了百度地图,在导入SDK后遇到了一些问题 编译错误: linker command failed with exit code 1 (use -v to see invocation) 想了很多办法,查了很多资料,最后终于解决. 可能原因: 1. 有重复的.m文件,或者未导入 解决办法:有重复的删除即可 在工作左边导航栏Target-->Build Phases-->compile Sources中,第三库库的所有.m文件都添加到里面 2.Valid Architectures 的值 在

iOS开发多线程篇—线程间的通信

iOS开发多线程篇—线程间的通信 一.简单说明 线程间通信:在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信 线程间通信的体现 1个线程传递数据给另1个线程 在1个线程中执行完特定任务后,转到另1个线程继续执行任务 线程间通信常用方法 - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait; - (void)performSelector:(SE

ios开发笔记----exc_bad_access(code=1, address=0x789870)野指针错误,假死debug状态

错误原因: exc_bad_access(code=1, address=0x789870)野指针错误,主要的原因是,当某个对象被完全释放,也就是retainCount,引用计数为0后.再去通过该对象去调用其它的方法就会出现野指针错误. 例如: Person *jerry = [[Person alloc]init];  //  retainCount引用计数为1 [jerry eat];  //  调用吃的方法 [jerry release];  //  释放jerry这个对象到 retain

iOS开发笔记-两种单例模式的写法

iOS开发笔记-两种单例模式的写法 单例模式是开发中最常用的写法之一,iOS的单例模式有两种官方写法,如下: 不使用GCD #import "ServiceManager.h" static ServiceManager *defaultManager; @implementation ServiceManager +(ServiceManager *)defaultManager{ if(!defaultManager) defaultManager=[[self allocWith

iOS开发多线程篇—线程安全 - 文顶顶

原文  http://www.cnblogs.com/wendingding/p/3805841.html iOS开发多线程篇—线程安全 一.多线程的安全隐患 资源共享 1 块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源 比如多个线程访问同一个对象.同一个变量.同一个文件 当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题 示例一: 示例二: 问题代码: 1 // 2 // YYViewController.m 3 // 05-线程安全 4 // 5 // Create

iOS开发多线程篇—线程的状态 - 文顶顶

原文  http://www.cnblogs.com/wendingding/p/3807184.html iOS开发多线程篇-线程的状态 一.简单介绍 线程的 创建 : self.thread=[[NSThread alloc]initWithTarget:self selector:@selector(test) object:nil]; 说明:创建线程有多种方式,这里不做过多的介绍. 线程的 开启 : [self.thread start]; 线程的 运行 和 阻塞 : (1)设置线程阻塞

iOS开发多线程篇—线程安全

iOS开发多线程篇—线程安全 一.多线程的安全隐患 资源共享 1块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源 比如多个线程访问同一个对象.同一个变量.同一个文件 当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题 示例一: 示例二: 问题代码: 1 // 2 // YYViewController.m 3 // 05-线程安全 4 // 5 // Created by apple on 14-6-23. 6 // Copyright (c) 2014年 itcase.

iOS开发多线程篇—线程间的通信(转)

这里转载 给自己一个备份 一.简单说明 线程间通信:在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信 线程间通信的体现 1个线程传递数据给另1个线程 在1个线程中执行完特定任务后,转到另1个线程继续执行任务 线程间通信常用方法 - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait; - (void)performSelector:(SEL)aS

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

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