多线程

这篇博客介绍了iOS应用中实现多线程的多种方法,包括使用`NSOperation`、`NSOperationQueue`、`NSThread`以及GCD(Grand Central Dispatch)。作者展示了如何在不同场景下使用这些技术,如在`AppDelegate`和`ViewController`中,以及如何处理网络请求和UI更新。通过示例代码,读者可以理解如何创建和管理线程,以避免主线程阻塞,提高应用性能。
摘要由CSDN通过智能技术生成
//
//  AppDelegate.h
//  UI21_多线程
//
//  Created by dllo on 15/8/26.
//  Copyright (c) 2015年 dllo. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;


@end
//
//  AppDelegate.m
//  UI21_多线程
//
//  Created by dllo on 15/8/26.
//  Copyright (c) 2015年 dllo. All rights reserved.
//

#import "AppDelegate.h"

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

@end

//
//  ViewController.h
//  UI21_多线程
//
//  Created by dllo on 15/8/26.
//  Copyright (c) 2015年 dllo. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController


@end

//
//  ViewController.m
//  UI21_多线程
//
//  Created by dllo on 15/8/26.
//  Copyright (c) 2015年 dllo. All rights reserved.
//

#import "ViewController.h"
#import "MyOperation.h"
#import "MBProgressHUD.h"
#import "AFNetworking.h"
@interface ViewController ()
@property(nonatomic,retain)UIButton *button;
@property(nonatomic,retain)UIImageView *image;
@end

@implementation ViewController
- (void)dealloc{
    [_button release];
    [_image release];
    [super dealloc];


}
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.button=[UIButton buttonWithType:UIButtonTypeSystem];
    self.button.frame=CGRectMake(100, 100, 150, 50);
    [self.button setTitle:@"测试" forState:UIControlStateNormal];
    [self.view addSubview:self.button];
    self.button.layer.borderWidth=3;
    self.button.layer.borderColor=[UIColor orangeColor].CGColor;
    self.button.layer.cornerRadius=10;
    self.button.layer.masksToBounds=YES;
    [self.button addTarget:self action:@selector(GCDAction:) forControlEvents:UIControlEventTouchUpInside];
    self.image=[[UIImageView alloc] initWithFrame:CGRectMake(100, 200, 150, 150)];
    self.image.backgroundColor=[UIColor orangeColor];
    [self.view addSubview:self.image];
    [_image release];
///下载PDF文件
//    NSURL *url=[NSURL URLWithString:@"http://h.hiphotos.baidu.com/zhidao/pic/item/d8f9d72a6059252dd3ed6d51319b033b5ab5b9e8.jpg"];
//    NSData *data=[NSData dataWithContentsOfURL:url];
//    UIImage *images=[UIImage imageWithData:data];
//    self.image.image=images;
//
//    //1.创建一个加载的效果图MB
//    MBProgressHUD *hud=[MBProgressHUD showHUDAddedTo:self.view animated:YES];
//    hud.labelText=@"正在下载....";
//    //设置样式
//    hud.mode=MBProgressHUDModeDeterminate;
//    //创建一个请求
//    NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://help.adobe.com/archive/en/photoshop/cs6/photoshop_reference.pdf"]];
//    AFHTTPRequestOperation *operation=[[AFHTTPRequestOperation alloc] initWithRequest:request];
//    //指定一个文件保存路径,放到沙盒路径的cashes文件里
//    NSArray *sandBox=NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
//    NSString *cachesPath=sandBox[0];
//    NSString *pdfPath=[cachesPath stringByAppendingPathComponent:@"test.pdf"];
//    NSLog(@"%@",pdfPath);
//    //把文件夹下载到指定的文件夹路径下,写成相应的文件名..
//    operation.outputStream=[NSOutputStream outputStreamToFileAtPath:pdfPath append:NO];
//    //通过AF进行下载
//    //这是下载进度的一个block里面会返回当前的下载进度,在这个block里设置hud的进度显示
//    [operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
//        hud.progress=(1.0)*(totalBytesRead)/totalBytesExpectedToRead;
//    }];
//    //当下载结束之后,控制进度的hud应该消失,所以我们通过af进行下载,完成的进度判断
//    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
//        NSLog(@"下载成功");
//        //拿掉hud
//        [hud removeFromSuperview];
//    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//        NSLog(@"下载失败");
//        [hud removeFromSuperview];
//    }];
//    //把任务添加到队列里
//    NSOperationQueue *queue=[[NSOperationQueue alloc] init];
//    [queue addOperation:operation];

}
- (void)click:(UIButton *)button{
///线程卡死
    NSInteger a=0;
    for (NSInteger i=0; i<1000000000; i++) {
        a++;
        NSLog(@"%ld",a);
    }
    NSLog(@"%ld",a);
}
#pragma mark 第一种解决县城的问题的方法,nsobject提供的方法
-(void)NSObjectThread:(UIButton *)button{
    [self performSelectorInBackground:@selector(click:) withObject:button];
     //优点:写法特别简单.能快速开辟一个临时线程
     //缺点:不能保证线程使用时数据的绝对安全

}
#pragma mark 第二种方式
-(void)NSThreadAction:(UIButton *)button{
//NSThread 本身就是一个线程类,它可以控制线程休眠或者创建..
    //当前的主线程
    NSLog(@"%@",[NSThread currentThread]);
    //主线程休眠3s
//    [NSThread sleepForTimeInterval:3];
//    NSLog(@"0002112121");
    //如果用创建对象,创建出来的就是新的线程..
    NSThread *thread=[[[NSThread alloc] initWithTarget:self selector:@selector(click:) object:nil] autorelease];
    //可以给新的线程对象起名
    thread.name=@"kitty";
    //启动子线程.
    [thread start];
    //优点:可以直接通过创建的方式来控制线程.
    //缺点:什么都需要手动设置,包括名,开始.太麻烦..

}
#pragma mark 第三种 NSOperation 任务
- (void)operationAction:(UIButton *)button{
//NSOperation 是一个抽象类,如果想使用这个抽象类必须创建一个他的子类
    MyOperation *operation=[[MyOperation alloc] init];
    [operation start];
    //它不能单独拿来使用,,如果单独使用和之前不考虑线程的方式是一样的会卡死住线程,他一般和NSOperationQueue配合使用...

}
-(void)operationQueue:(UIButton *)button{
//队列和任务一起配合使用解决多线程的问题..
    //队列:队列中通过一个线程池来管理所有闲置的线程,这样就可以提高线程的重用率,避免重复的创建线程,,整合资源
    //优点:内部不需要关心线程的安全问题,用起来相对简单//
    //缺点:效率稍微优点低...

    NSOperationQueue *queue=[[NSOperationQueue alloc] init];
    //设置最大并发数..
    [queue setMaxConcurrentOperationCount:2];
    MyOperation *op1=[[MyOperation alloc] init];
    MyOperation *op2=[[MyOperation alloc] init];
    MyOperation *op3=[[MyOperation alloc] init];
    MyOperation *op4=[[MyOperation alloc] init];
    MyOperation *op5=[[MyOperation alloc] init];
//把任务加到队列里
     [queue addOperation:op1];
     [queue addOperation:op2];
     [queue addOperation:op3];
     [queue addOperation:op4];
     [queue addOperation:op5];

}
- (void)GCDAction:(UIButton *)button{
GCD是苹果提供的一种多处理线程的解决方案,整体比较好,和operationQueue两种是常见的解决线程问题的方法
//    //这个方法可以保证无论哪个线程执行都只执行一次..
//    static dispatch_once_t oneToken;
//    dispatch_once(&oneToken, ^{
//
//    });
//    ///自定义一个队列
//    //第一个参数:给队列起一个名字
//    //第二个参数:设置队列并行..
//    dispatch_queue_t myQueue=dispatch_queue_create("kitty", DISPATCH_QUEUE_CONCURRENT);
//    //接下来,.可以再队列里进行一些任务
//    dispatch_async(myQueue, ^{
//        //任务写在block里
//        NSInteger count=0;
//        for (NSInteger i=0; i<5000000; i++) {
//            count++;
//        }
//        NSLog(@"%ld",count);
//    });
    ///网络请求一般会在子线程里进行记载,但是显示这个数据都是在主线程里进行的,所以需要把请求的数据放到主线程使用
    //定义一个全局的队列
//第一个参数:设置当前队列优先
//第二个参数:设置实际含义,留给以后用
dispatch_queue_t globalQueue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    //再获取一下当前的队列,也就是主线程
    dispatch_queue_t mainQueue=dispatch_get_main_queue();
    //通过异步进行数据请求
    dispatch_async(globalQueue, ^{
        //通过网址请求图片数据
        NSString *picUrl=@"http://img4.duitang.com/uploads/item/201207/28/20120728105310_jvAjW.thumb.600_0.jpeg";
        NSURL *url=[NSURL URLWithString:picUrl];
        NSData *data=[NSData dataWithContentsOfURL:url];
        UIImage *image=[UIImage imageWithData:data];
        //把请求下来的数据到主线程进行刷新
        dispatch_async(mainQueue, ^{
            self.image.image=image;
        });
    });
[NSURLConnection sendAsynchronousRequest:nil queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
      
}];





}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

//
//  MyOperation.h
//  UI21_多线程
//
//  Created by dllo on 15/8/26.
//  Copyright (c) 2015年 dllo. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface MyOperation : NSOperation

@end

//
//  MyOperation.m
//  UI21_多线程
//
//  Created by dllo on 15/8/26.
//  Copyright (c) 2015年 dllo. All rights reserved.
//

#import "MyOperation.h"

@implementation MyOperation
-(void)main{
    NSInteger count=1;
    for (NSInteger i=0; i<1000000; i++) {
        count++;
    }
    NSLog(@"%ld",count);
}

@end


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值