iOS开发多线程网络———NSThread

iOS开发多线程网络———NSThread

NSThread概念 

            NSThree是官方推荐的线程处理方式,它在处理机制上,需要开发者负责手动管理Thread的生命周期,包括子线程与主线程之间的同步等。线程共享同一应用程序的部分内存空间,它们拥有对数据相同的访问权限。你得协调多个线程 对同一数据的访问,一般做法是在访问之前加锁,在 iOS 中我们可以使用多种形式的 thread。 比其他两个轻量级 需要自己管理线程的生命周期,线程同步。 线程同步对数据的加锁会有一定的系统开销

NSObject的多线程方法

          a.开启后台执行任务的方法

       - (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg

           b.在后台线程中通知主线程执行任务的方法

       - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait

           c.获取线程信息 

     [NSThreadcurrentThread]

           d.线程休眠

     [NSThread sleepForTimeInterval:2.0f];

特点:

       使用简单,量级轻

       不能控制线程的数量以及执行顺序 

 示例代码:

   1 #import "LDViewController.h"

  2 /**
  3  需求分析
  4  
  5  1. UIImageView显示图片
  6  2. UIImage模拟从网络上下载
  7  3. NSString记录图片路径
  8  
  9  小结
 10  
 11  方法,看起来很简单,
 12  
 13  1> 不能够自动回收线程,如果并发数量多,会建立大量的子线程!
 14  2> 使用NSThread的线程,不会自动添加autoreleasepool
 15  
 16     意味着,如果在后台线程方法中,
 17  
 18  @autoreleasepool {} 自动释放池
 19  
 20  主线程中是有自动释放池的,使用GCD和NSOperation也会自动添加自动释放池
 21  
 22  NSThread和NSObject不会,如果在后台线程中创建了autorelease的对象,需要使用自动释放池,否则会出现内存泄漏!
 23  
 24  工作原理:
 25  
 26  1. 当自动释放池被销毁或者“耗尽”时,对池中的所有对象发送release消息,清空自动释放池
 27  2. 所有autorelease的对象,在出了作用域之后,会自动添加到【最近一次创建的自动释放池中】自动释放池中
 28  
 29  在ARC中,编译器在编译过程中,会自动根据代码结构,添加retain和release。
 30  */
 31 @interface LDViewController ()
 32 
 33 @property (nonatomic, strong) UIImageView *imageView;
 34 @property (nonatomic, strong) UIImage *image;
 35 @property (nonatomic, strong) NSString *imagePath;
 36 
 37 @end
 38 
 39 @implementation LDViewController
 40 
 41 // 0. 模拟使用图像路径加载图片
 42 - (void)setImagePath:(NSString *)imagePath
 43 {
 44     @autoreleasepool {
 45         NSLog(@"%@", [NSThread currentThread]);
 46         
 47         // 1> 模拟下载,延时
 48         [NSThread sleepForTimeInterval:1.0];
 49 
 50         // 2> 设置图像,苹果底层允许使用performSelectorInBackground方法
 51         // 在后台线程更新UI,强烈不建议大家这么做!
 52         // YES会阻塞住线程,直到调用方法完成
 53         // NO不会阻塞线程,会继续执行
 54         [self performSelectorOnMainThread:@selector(setImage:) withObject:[UIImage imageNamed:imagePath] waitUntilDone:NO];
 55     }
 56 }
 57 
 58 // 1. 图像
 59 - (void)setImage:(UIImage *)image
 60 {
 61     
 62     self.imageView.image = image;
 63     
 64 //    [NSThread sleepForTimeInterval:1.0];
 65     // 根据图片自动调整大小
 66     [self.imageView sizeToFit];
 67 }
 68 
 69 // 2. 创建imageView
 70 - (UIImageView *)imageView
 71 {
 72     if (!_imageView) {
 73         _imageView = [[UIImageView alloc] init];
 74     }
 75     
 76     return _imageView;
 77 }
 78 
 79 - (void)viewDidLoad
 80 {
 81     [super viewDidLoad];
 82     
 83     [self.view addSubview:self.imageView];
 84     
 85     // 在后台线程执行这段代码即可
 86     for (int i = 0; i < 50; ++i) {
 87         [self performSelectorInBackground:@selector(setImagePath:) withObject:@"头像1.png"];
 88     }
 89 //    [self setImagePath: @"头像1.png"];
 90 }
 91 
 92 - (void)demo
 93 {
 94     // 提问:代码存在什么问题?如果循环次数非常大,会出现什么问题?应该如何修改?
 95     
 96     // 解决办法1:如果i比较大,可以用@autoreleasepool(在for循环外)
 97     // 解决方法2:如果i玩命大,一次循环都会造成自动释放池被填满可以用@autoreleasepool(在for循环内如下:)
 98     for (int i = 0; i < 10000000; ++i) {
 99         @autoreleasepool {
100             // *
101             NSString *str = @"Hello World!";
102             // new *
103             str = [str uppercaseString];
104             // new *
105             str = [NSString stringWithFormat:@"%@ %d", str, i];
106             
107             NSLog(@"%@", str);
108         }
109     }
110 }
111 
112 @end

 NSObject的多线程方法注意事项:

 a.NSObject的多线程方法使用的是NSThread得多线程技术,而NSThread的多线程技术不会自动使用@autoreleasepool

 b.在使用NSObject或NSThread的多线程技术时,如果涉及到对象分配,需要手动添加@autoreleasepool 

 @autoreleasepool 简单介绍

 1.iOS开发中的内存管理

       a.iOS开发中,并没有JAVAC#中的垃圾回收机制

        b.使用ARC开发,只是在编译时,编译器会根据代码结构自动添加了retainreleaseautorelease

2.自动释放池的工作原理
a.标记为autorelease的对象在出了作用域范围后,会被添加到最近一次创建的自动释放池中
b.当自动释放池被销毁耗尽时,会向自动释放池中的所有对象发送release消息
c.每个线程都需要有@autoreleasepool,否则可能会出现内存泄漏,但是使用NSThread多线程技术,并不会为后台线程创建自动释放池

 

iOS开发多线程网络———NSThread,布布扣,bubuko.com

iOS开发多线程网络———NSThread

上一篇:【Android】IntentService & HandlerThread源码解析


下一篇:android处理url中的特殊字符