[精通Objective-C]三种实现并发编程的方式
参考书籍:《精通Objective-C》【美】 Keith Lee
目录
线程
隐式创建并启动线程
使用NSObject类中的performSelectorInBackground: withObject:
方法可以隐式地创建和启动用于执行对象中方法的新线程。该线程会作为后台次要进程立刻启动,而当前进程会立刻返回。下面是一个使用该方法的实例:
首先创建一个继承于NSObject类的,含有将由独立线程执行的方法的类:
#import <Foundation/Foundation.h>
@interface ConcurrentProcessor : NSObject
@property(readwrite) BOOL isFinished;
@property(readonly) NSInteger computeResult;
-(void)computeTask:(id)data;
@end
#import "ConcurrentProcessor.h"
@interface ConcurrentProcessor()
@property(readwrite)NSInteger computeResult;
@end
@implementation ConcurrentProcessor
{
NSString *computeID; // @synchronized指令锁定的唯一对象
NSUInteger computeTasks; // 并行计算任务的计数
NSLock *computeLock; // 锁对象
}
-(id)init{
if ((self = [super init])) {
_isFinished = NO;
_computeResult = 0;
computeLock = [NSLock new];
computeID = @"1";
computeTasks = 0;
}
return self;
}
-(void)computeTask:(id)data{
NSAssert(([data isKindOfClass:[NSNumber class]]), @"Not an NSNumber instance");
NSUInteger computations = [data unsignedIntegerValue];
// 配置线程环境时应在线程入口点创建自动释放池与异常处理程序
@autoreleasepool {
@try {
if ([[NSThread currentThread] isCancelled]) {
return;
}
// @synchronized指令括号内为唯一标识符,标识符保护的代码块对象只能同时被最多一个线程访问
@synchronized (computeID) {
// 增加活动任务的计数
computeTasks++;
}
// 获取锁并执行关键代码部分中的计算操作
[computeLock lock];
if ([[NSThread currentThread] isCancelled]) {
[computeLock unlock];
return;
}
NSLog(@"Performing computations %lu",computations);
for (int ii = 0; ii < computations; ii++) {
self.computeResult = self.computeResult + 1;
}
// 完成计算并解除锁
[computeLock unlock];
// 模拟额外的处理时间
[NSThread sleepForTimeInterval:1.0];
// 减少活动任务数,如果数量为0,则更新标志位
@synchronized (computeID) {
computeTasks--;
if (!computeTasks) {
self.isFinished = YES;
}
}
} @catch (NSException *exception) {}
}
}
@end
最后在main.m中进行测试:
#import <Foundation/Foundation.h>
#import "ConcurrentProcessor.h"