IOS 创建并发线程的实例详解

IOS 创建并发线程的实例详解

创建并发线程

主线程一般都是处理UI界面及用户交互的事儿的。其他的事一般就要另外的线程去处理,如下载,计算等。。。
现在先简单创建3个线程,分别打印出1-1000,,为了方便,线程3就放在主线程中执行。

- (void) firstCounter{
@autoreleasepool {
NSUInteger counter = 0;
for (counter = 0;
counter < 1000;
counter++){
NSLog(@"First Counter = %lu", (unsigned long)counter);
}
}
}
- (void) secondCounter{
@autoreleasepool {
NSUInteger counter = 0;  

for (counter = 0;
counter < 1000;
counter++){
NSLog(@"Second Counter = %lu", (unsigned long)counter);
}
}
}
- (void) thirdCounter{
NSUInteger counter = 0;
for (counter = 0;
counter < 1000;
counter++){
NSLog(@"Third Counter = %lu", (unsigned long)counter);
}
}
- (void)viewDidLoad {
[super viewDidLoad];
[NSThread detachNewThreadSelector:@selector(firstCounter)
toTarget:self
withObject:nil];
[NSThread detachNewThreadSelector:@selector(secondCounter)
toTarget:self
withObject:nil];
/* Run this on the main thread */
[self thirdCounter];
}

由于thirdCounter 函数没有运行在单独的线程中,所以不需要自动释放池(autorelease pool)。这个方法将在应用程序的主线程中运行,每一个Cocoa Touch程序都会自
动的给该主线程创建一个自动释放池。

在代码的最后通过调用 detachNewThreadSelector,把将第一个计数器和第二个计数器运行在独立的线程中。现在,如果你运行程序,将会在控制台窗口看到如下信息:

 Second Counter = 921
Third Counter = 301
Second Counter = 922
Second Counter = 923
Second Counter = 924
First Counter = 956
Second Counter = 925
Counter = 957
Second Counter = 926
First Counter = 958
Third Counter = 302
Second Counter = 927
Third Counter = 303
Second Counter = 928

可以看出,这三个计时器是同时运行的,他们输出的内容是随机交替的。 每一个线程必须创建一个 autorelease pool。在 autorelease pool 被 release 之前,autorelease pool 会一直持有被 autoreleased 的对象的引用。在引用计数内存管理环境中这是一个非常重要的机制,例如Cocoa Touch中的对象就能够被autoreleased。无论何时,在创建一个对象实例时,该对象的引用计数是1,但是当创建的autorelease pool对象被release了,那么 autorelease 的对象同样会发送一个 release 消息,如果此时,它的引用计数仍然是 1,那么该对象将被销毁。

每一个线程都需要创建一个 autorelease pool,当做是该线程第一个被创建的对象。如果不这样做,如果不这样做,当线程退出的时候,你分配在线程中的对象会发生内存泄露。为了更好的理解,我们来看看下面的代码:

- (void) autoreleaseThread:(id)paramSender{
NSBundle *mainBundle = [NSBundle mainBundle];
NSString *filePath = [mainBundle pathForResource:@"AnImage"
ofType:@"png"];
UIImage *image = [UIImage imageWithContentsOfFile:filePath];
/* Do something with the image */
NSLog(@"Image = %@", image);
}
- (void)viewDidLoad {
[super viewDidLoad];
[NSThread detachNewThreadSelector:@selector(autoreleaseThread:)
toTarget:self
withObject:self];
}
如果你运行这段代码,,你就会在控制台窗口看到这样的输出信息:
*** __NSAutoreleaseNoPool(): Object 0x5b2c990 of
class NSCFString autoreleased with no pool in place - just leaking
*** __NSAutoreleaseNoPool(): Object 0x5b2ca30 of
class NSPathStore2 autoreleased with no pool in place - just leaking
*** __NSAutoreleaseNoPool(): Object 0x5b205c0 of
class NSPathStore2 autoreleased with no pool in place - just leaking
*** __NSAutoreleaseNoPool(): Object 0x5b2d650 of
class UIImage autoreleased with no pool in place - just leaking

上面的信息显示了我们创建的 autorelease 的 UIImage 实例产生了一个内存泄露,另外,FilePath 和其他的对象也产生了泄露。这是因为在我们的线程中,没有在开始的时候创建和初始化一个autorelease pool。下面是正确的代码,你可以测试一下,确保它没有内存泄露:

- (void) autoreleaseThread:(id)paramSender{
@autoreleasepool {
NSBundle *mainBundle = [NSBundle mainBundle];
NSString *filePath = [mainBundle pathForResource:@"AnImage"
ofType:@"png"];
UIImage *image = [UIImage imageWithContentsOfFile:filePath];
/* Do something with the image */
NSLog(@"Image = %@", image);
}
}

以上使用关于IOS 并发线程的实例,如有疑问大家可以留言讨论,共同进步,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • IOS 线程死锁详细介绍

    iOS线程死锁 前言: 在chat view的开发过程中,添加了"混合标签添加与显示",app出现发送图片会出现卡死的情况,但过了大约30-40 second后会恢复正常. 问题分析: 因为没有任何报错与提示,只能根据表面现象慢慢分析,经过多次测试与观察得出以下规律: (1)发送表情与文本不会发生该情况,只有发送图片才会发生app界面卡死的情况.(主线程阻塞,与大文件上传有关)      (2)app卡死一定时间后会恢复正常,但时间不定,大约范围在30-40 second.(主线程解除

  • IOS多线程实现多图片下载(一)

    在没有步入正文之前先给大家展示下效果图,如果大家觉得很满意请继续往下阅读全文. 大家可以看到这个界面很简单,其实就是UITableView的布局,但是难点是在于如何从网上下载这些图片,下载之后应如何进行存储! 我们一步一步进行解析,先从单线程(主线程)进行多图片下载我们布局上的文字及图片的地址从plist文件中进行读取 根据结构,我们自定义一个数据模型文件 DDZApp.h #import <Foundation/Foundation.h> @interface DDZApp : NSObje

  • iOS开发网络篇—实现大文件的多线程断点下载

    说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时开启多条线程下载一个较大的文件.因为实现过程较为复杂,所以下面贴出完整的代码. 实现思路:下载开始,创建一个和要下载的文件大小相同的文件(如果要下载的文件为100M,那么就在沙盒中创建一个100M的文件,然后计算每一段的下载量,开启多条线程下载各段的数据,分别写入对应的文件部分). 项目中用到的主要类如下: 完成的实现代码如下: 主控制器中的代码: #import "YYViewController.h" #import

  • 详解iOS 多线程 锁 互斥 同步

    在iOS中有几种方法来解决多线程访问同一个内存地址的互斥同步问题: 方法一,@synchronized(id anObject),(最简单的方法) 会自动对参数对象加锁,保证临界区内的代码线程安全 @synchronized(self) { // 这段代码对其他 @synchronized(self) 都是互斥的 // self 指向同一个对象 } 方法二,NSLock NSLock对象实现了NSLocking protocol,包含几个方法: lock,加锁 unlock,解锁 tryLock

  • 详解iOS多线程之2.NSThread的加锁@synchronized

    那什么时候需要加锁呢,就是当多条线程同时操作一个变量时,就需要加锁了. 上代码 声明变量 @interface ViewController () @property (strong, nonatomic)NSThread *thread1; @property (strong, nonatomic)NSThread *thread2; @property (strong, nonatomic)NSThread *thread3; @property (assign, nonatomic)int

  • 详解iOS中多线程app开发的GCD队列的使用

    GCD的基本使用 一.主队列介绍 主队列:是和主线程相关联的队列,主队列是GCD自带的一种特殊的串行队列,放在主队列中得任务,都会放到主线程中执行. 提示:如果把任务放到主队列中进行处理,那么不论处理函数是异步的还是同步的都不会开启新的线程. 获取主队列的方式: 复制代码 代码如下: dispatch_queue_t queue=dispatch_get_main_queue(); (1)使用异步函数执行主队列中得任务,代码示例: 复制代码 代码如下: // //  YYViewControll

  • 在IOS中为什么使用多线程及多线程实现的三种方法

    多线程是一个比较轻量级的方法来实现单个应用程序内多个代码执行路径. 在系统级别内,程序并排执行,程序分配到每个程序的执行时间是基于该程序的所需时间和其他程序的所需时间来决定的. 然而,在每个程序内部,存在一个或者多个执行线程,它同时或在一个几乎同时发生的方式里执行不同的任务. 概要提示: iPhone中的线程应用并不是无节制的,官方给出的资料显示,iPhone OS下的主线程的堆栈大小是1M,第二个线程开始就是512KB,并且该值不能通过编译器开关或线程API函数来更改,只有主线程有直接修改UI

  • IOS 创建并发线程的实例详解

    IOS 创建并发线程的实例详解 创建并发线程 主线程一般都是处理UI界面及用户交互的事儿的.其他的事一般就要另外的线程去处理,如下载,计算等... 现在先简单创建3个线程,分别打印出1-1000,,为了方便,线程3就放在主线程中执行. - (void) firstCounter{ @autoreleasepool { NSUInteger counter = 0; for (counter = 0; counter < 1000; counter++){ NSLog(@"First Cou

  • iOS中的线程死锁实例详解

    什么是线程死锁 是指两个或两个以上的线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去. 线程死锁怎么发生 发生死锁的情况一般是两个对象的锁相互等待造成的. 死锁发生的条件 1.互斥条件:所谓互斥就是进程在某一时间内独占资源. 2.请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放. 3.不剥夺条件:进程已获得资源,在末使用完之前,不能强行剥夺. 4.循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系. 死锁通常是一个线程锁定了一

  • IOS文件的简单读写实例详解

    IOS文件的简单读写实例详解 数组(可变与不可变)和字典(可变与不可变)中元素对象的类型,必须是NSString,NSArray,NSDictionary,NSData,否则不能直接写入文件 #pragma mark---NSString的写入与读取--- //1:获取路径 NSString *docunments = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)firstObje

  • 基于iOS Realm数据库的使用实例详解

    首先下载Realm源代码,https://realm.io/cn/docs/objc/latest 将下载的文件解压,从 ios/static/ 目录中将 Realm.framework 拖曳到 Xcode 工程的文件导航器内,然后在 Xcode 文件导航器中选中工程.然后选择应用目标,前往 Build Phases 选项卡.在 Link Binary with Libraries 部分中单击 + 按钮,然后添加 libc++.tbd 和 libz.tbd.这样还没有完,我们还需要安装插件,打开

  • Spring boot注解@Async线程池实例详解

    这篇文章主要介绍了Spring boot注解@Async线程池实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 从Spring3开始提供了@Async注解,该注解可以被标注在方法上,以便异步地调用该方法.调用者将在调用时立即返回,方法的实际执行将提交给Spring TaskExecutor的任务中,由指定的线程池中的线程执行. 1. TaskExecutor Spring异步线程池的接口类,其实质是java.util.concurrent

  • IOS 获取APP 版本号的实例详解

    IOS 获取APP 版本号的实例详解 看代码的时候看到一句,用于获取.plist文件的版本号 labelVersion.text = [NSString stringWithFormat:@"v%@", [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString*)kCFBundleVersionKey]]; 比较感兴趣的是后面的参数 kcFBundleVersionKey ,竟然是CFBundle.h已经定于好的属性,下面有

  • IOS UITableView颜色设置的实例详解

    IOS UITableView颜色设置的实例详解 1.系统默认的颜色设置  //无色 cell.selectionStyle = UITableViewCellSelectionStyleNone; //蓝色 cell.selectionStyle = UITableViewCellSelectionStyleBlue; //灰色 cell.selectionStyle = UITableViewCellSelectionStyleGray; 2.自定义颜色和背景设置 改变UITableView

  • mysql创建删除表的实例详解

    表的创建命令需要: 表的名称 字段名称 定义每个字段(类型.长度等) 语法 下面是通用的SQL语法用来创建MySQL表: CREATE TABLE table_name (column_name column_type); 现在,我们将在 test 数据库中创建以下表. create table tutorials_tbl( tutorial_id INT NOT NULL AUTO_INCREMENT, tutorial_title VARCHAR(100) NOT NULL, tuto

  • selenium 与 chrome 进行qq登录并发邮件操作实例详解

    selenium 与 chrome 进行qq登录并发邮件操作实例详解 出现的问题: qq邮箱各种iframe需要切换,延时是必须的,通过各种方法找元素,qq邮件正文的iframe name是变化的,其他几种方法都不行,最后居然用这样搞定.o[0].click() , o[0].send_keys("abc"),还得再研究研究!!! 备注:已经在机器上登录过QQ客户端,XXXX是发送QQ号,YYYYY是接受QQ号 from selenium import webdriver import

  • java简单实现多线程及线程池实例详解

    本文为大家分享了java多线程的简单实现及线程池实例,供大家参考,具体内容如下 一.多线程的两种实现方式 1.继承Thread类的多线程 /** * 继承Thread类的多线程简单实现 */ public class extThread extends Thread { public void run(){ for(int i=0;i<100;i++){ System.out.println(getName()+"-"+i); } } public static void mai

随机推荐