【Objective-C】多线程

(一)线程:

NSThread类的使用,直接上代码:

-(void)testThread1 {
    NSString *param = @"Task 1";
    //新建线程
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(onExecuteTask1:) object:param];
    //启动线程
    [thread start];
    
    //为测试子线程执行完整,这里让主线程休眠
    [NSThread sleepForTimeInterval:3];
}

-(void)onExecuteTask1:(NSString *) param{
    @autoreleasepool {
        [NSThread sleepForTimeInterval:1];
        NSLog(@"thread = %@, param = %@", [NSThread currentThread], param);
    }
}
注1:新建线程时param参数不是必须的,可不带。

注2:子线程的内存管理由子线程自己去负责的,这里使用@autoreleasepool来做自动释放处理。

另外,NSThread类中定义了NSObject (NSThreadPerformAdditions)类别,故可以在任意对象类中,使用以下方法实现线程的作用:

//调用子线程执行@selector指定的方法
- (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg;
//调用主线程执行@selector指定的方法,在iOS开发中,子线程通过此方法调用主线程更新UI相当方便有用
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;

(二)线程池

NSOperation类:可理解为一个要执行的任务,相当于Java语言里的Runnable或Callback;

NSOperationQueue类:任务执行队列、线程池。任务池可以添加NSOperation实例,还可以添加代码块。下面是这两个方法的定义:

- (void)addOperation:(NSOperation *)op;
- (void)addOperationWithBlock:(void (^)(void))block;

在Java里面,要定义一个任务类,可以通过实现Runnable接口或Callback接口。同理,在Objective-C中,可以定义一个类继承NSOperation类,实现main()方法执行相应的耗时代码。如下:

#import 

@interface MyOperation : NSOperation {
    NSString *_param;
}

-(id)initWithParam:(NSString *)param;

@end

#import "MyOperation.h"

@implementation MyOperation

-(id)initWithParam:(NSString *)param {
    if(self = [super init]) {
        _param = param;
    }
    return self;
}

-(void)main {
    @autoreleasepool {
        [NSThread sleepForTimeInterval:1];
        NSLog(@"thread = %@, param = %@", [NSThread currentThread], _param);
    }
}

@end

另外,Objective-C自带了NSInvocationOperation类,它继承自NSOperation类。它可以方便地异步执行某个方法,跟NSThread一样的用法。如下:

NSInvocationOperation *task_a = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(onExecuteTask2:) object:param_a];

完整代码如下:

-(void)testThread2 {
    NSString *param_a = @"Task 2 a";
    NSString *param_b = @"Task 2 b";
    NSString *param_c = @"Task 2 c";
    //新建任务
    NSInvocationOperation *task_a = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(onExecuteTask2:) object:param_a];
    NSOperation *task_b = [[MyOperation alloc] initWithParam:param_b];
    //依赖关系:任务b执行完后才执行任务a
    [task_a addDependency:task_b];
    //新建线程池
    NSOperationQueue *taskQueue = [[NSOperationQueue alloc] init];
    //主线程队列
    //NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
    //设置最大的并发线程数
    [taskQueue setMaxConcurrentOperationCount:3];
    //添加任务(NSOperation对象)到线程池,由线程池调度执行
    [taskQueue addOperation:task_a];
    [taskQueue addOperation:task_b];
    //添加任务(代码块)到线程池,由线程池调度执行
    [taskQueue addOperationWithBlock:^{
        NSLog(@"%@", param_c);
    }];
    
    //为测试子线程执行完整,这里让主线程休眠
    [NSThread sleepForTimeInterval:3];
}

-(void)onExecuteTask2:(NSString *) param {
    @autoreleasepool {
        [NSThread sleepForTimeInterval:1];
        NSLog(@"thread = %@, param = %@", [NSThread currentThread], param);
    }

}

(三)GCD

Grand Central Dispatch (GCD)是Apple开发的一个多核编程的较新的解决方法。它主要用于优化应用程序以支持多核处理器以及其他对称多处理系统。它是一个在线程池模式的基础上执行的并行任务。GCD的相关方法,均以“dispatch_”开发,例如,在我们在开发iOS应用时,经常会用到的如下代码:

dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
    //后台线程
    dispatch_async(dispatch_get_main_queue(), ^(void){
        //UI更新操作
    });
});


@容新华技术博客 - http://blog.csdn.net/rongxinhua - 原创文章,转载请注明出处


你可能感兴趣的:(Objective-C)