系统进程
AOP( 切面编程)
Aspects
MultipleThread
Thread
Pthreads
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
pthread_t thread;
//创建一个线程并自动执行
pthread_create(&thread, NULL, start, NULL);
}
void *start(void *data) {
NSLog(@"%@", [NSThread currentThread]);
return NULL;
}
NSThread
这套方案是经过苹果封装后的,并且完全面向对象的。所以你可以直接操控线程对象,非常直观和方便。但是,它的生命周期还是需要我们手动管理,所以这套方案也是偶尔用用,比如
- 先创建线程类,再启动
OBJECTIVE-C
` ``// 创建`` ``NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run:) object:nil];`` ``// 启动`` ``[thread start];`
SWIFT
` ``//创建`` ``let thread = NSThread(target: self, selector: ``"run:"``, object: nil)`` ``//启动`` ``thread.start()`
- 创建并自动启动
OBJECTIVE-C
` ``[NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:nil];`
SWIFT
` ``NSThread.detachNewThreadSelector(``"run:"``, toTarget: self, withObject: nil)`
常见方法
//取消线程
- (void)cancel;
//启动线程
- (void)start;
//判断某个线程的状态的属性
@property (readonly, getter=isExecuting) BOOL executing;
@property (readonly, getter=isFinished) BOOL finished;
@property (readonly, getter=isCancelled) BOOL cancelled;
//设置和获取线程名字
-(void)setName:(NSString *)n;
-(NSString *)name;
//获取当前线程信息
+ (NSThread *)currentThread;
//获取主线程信息
+ (NSThread *)mainThread;
//使当前线程暂停一段时间,或者暂停到某个时刻
+ (void)sleepForTimeInterval:(NSTimeInterval)time;
+ (void)sleepUntilDate:(NSDate *)date;
线程同步
线程跳转
我们都知道在其他线程操作完成后必须到主线程更新
Asynchronous
PromiseKit
Concurrence
GCD
Grand Central Dispatch,听名字就霸气。它是苹果为多核的并行运算提出的解决方案,所以会自动合理地利用更多的

队列获取与创建
- 主队列:特殊的串行队列
这是一个特殊的 串行队列。什么是主队列,大家都知道吧,它用于刷新
//OBJECTIVE-C
dispatch_queue_t queue = dispatch_get_main_queue();
//SWIFT
let queue = dispatch_get_main_queue()
- 全局并行队列
这应该是唯一一个并行队列,只要是并行任务一般都加入到这个队列。
//OBJECTIVE-C
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//SWIFT
let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
- 自建队列
自己可以创建 串行队列
//OBJECTIVE-C
dispatch_queue_t queue = dispatch_queue_create("tk.bourne.testQueue", NULL);
//SWIFT
let queue = dispatch_queue_create("tk.bourne.testQueue", nil);
任务
- 同步任务:不会新开线程
//OJC
dispatch_sync(, ^{
//code here
NSLog(@"%@", [NSThread currentThread]);
});
//Swift
dispatch_sync(, { () -> Void in
//code here
println(NSThread.currentThread())
})
- 异步任务:会新开线程
//OJC
dispatch_sync(, ^{
//code here
NSLog(@"%@", [NSThread currentThread]);
});
//Swift
dispatch_sync(, { () -> Void in
//code here
println(NSThread.currentThread())
})
Async:GCD 的语法糖
Async.background {
println("This is run on the background queue")
}.main {
println("This is run on the main queue, after the previous block")
}
在
use_frameworks!
pod "AsyncSwift"
即可以引入 (1)Supports the modern queue classes:
Async.main {}
Async.userInteractive {}
Async.userInitiated {}
Async.utility {}
Async.background {}
(2)Chain as many blocks as you want:
Async.userInitiated {
// 1
}.main {
// 2
}.background {
// 3
}.main {
// 4
}
(3)Store reference for later chaining:
let backgroundBlock = Async.background {
print("This is run on the background queue")
}
// Run other code here...
// Chain to reference
backgroundBlock.main {
print("This is run on the \(qos_class_self().description) (expected \(qos_class_main().description)), after the previous block")
}
(4)Custom queues:
let customQueue = dispatch_queue_create("CustomQueueLabel", DISPATCH_QUEUE_CONCURRENT)
let otherCustomQueue = dispatch_queue_create("OtherCustomQueueLabel", DISPATCH_QUEUE_CONCURRENT)
Async.customQueue(customQueue) {
print("Custom queue")
}.customQueue(otherCustomQueue) {
print("Other custom queue")
}
(5)Dispatch block after delay:
let seconds = 0.5
Async.main(after: seconds) {
print("Is called after 0.5 seconds")
}.background(after: 0.4) {
print("At least 0.4 seconds after previous block, and 0.9 after Async code is called")
}
(6)Cancel blocks that aren’t already dispatched:
// Cancel blocks not yet dispatched
let block1 = Async.background {
// Heavy work
for i in 0...1000 {
print("A \(i)")
}
}
let block2 = block1.background {
print("B – shouldn't be reached, since cancelled")
}
Async.main {
// Cancel async to allow block1 to begin
block1.cancel() // First block is _not_ cancelled
block2.cancel() // Second block _is_ cancelled
}
(7)Wait for block to finish – an ease way to continue on current queue after background task:
let block = Async.background {
// Do stuff
}
// Do other stuff
block.wait()
AsyncGroup
Multiple dispatch blocks with GCD:
let group = AsyncGroup()
group.background {
// Run on background queue
}
group.utility {
// Run on utility queue, in parallel to the previous block
}
group.wait()
All modern queue classes:
group.main {}
group.userInteractive {}
group.userInitiated {}
group.utility {}
group.background {}
Custom queues:
let customQueue = dispatch_queue_create("Label", DISPATCH_QUEUE_CONCURRENT)
group.customQueue(customQueue) {}
Wait for group to finish:
let group = AsyncGroup()
group.background {
// Do stuff
}
group.background {
// Do other stuff in parallel
}
// Wait for both to finish
group.wait()
// Do rest of stuff
Custom asynchronous operations:
let group = AsyncGroup()
group.enter()
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
// Do stuff
group.leave()
}
group.enter()
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
// Do other stuff in parallel
group.leave()
}
// Wait for both to finish
group.wait()
// Do rest of stuff
队列组
队列组可以将很多队列添加到一个组里,这样做的好处是,当这个组里所有的任务都执行完了,队列组会通过一个方法通知我们。下面是使用方法,这是一个很实用的功能。
//1.创建队列组
dispatch_group_t group = dispatch_group_create();
//2.创建队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//3.多次使用队列组的方法执行任务, 只有异步方法
//3.1.执行3次循环
dispatch_group_async(group, queue, ^{
for (NSInteger i = 0; i < 3; i++) {
NSLog(@"group-01 - %@", [NSThread currentThread]);
}
});
//3.2.主队列执行8次循环
dispatch_group_async(group, dispatch_get_main_queue(), ^{
for (NSInteger i = 0; i < 8; i++) {
NSLog(@"group-02 - %@", [NSThread currentThread]);
}
});
//3.3.执行5次循环
dispatch_group_async(group, queue, ^{
for (NSInteger i = 0; i < 5; i++) {
NSLog(@"group-03 - %@", [NSThread currentThread]);
}
});
//4.都完成后会自动通知
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"完成 - %@", [NSThread currentThread]);
});
NSOperation
1,
2,在
3,有
4,
创建任务
//1.创建NSBlockOperation对象
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"%@", [NSThread currentThread]);
}];
//2.开始任务
[operation start];
之前说过这样的任务,默认会在当前线程执行。但是
//1.创建NSBlockOperation对象
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"%@", [NSThread currentThread]);
}];
//添加多个Block
for (NSInteger i = 0; i < 5; i++) {
[operation addExecutionBlock:^{
NSLog(@"第%ld次:%@", i, [NSThread currentThread]);
}];
}
//2.开始任务
[operation start];
打印结果:
2015-07-28 17:50:16.585 test[17527:4095467] 第2次 -{number = 1, name = main}
2015-07-28 17:50:16.585 test[17527:4095666] 第1次 -{number = 4, name = (``null``)}
2015-07-28 17:50:16.585 test[17527:4095665]{number = 3, name = (``null``)}
2015-07-28 17:50:16.585 test[17527:4095662] 第0次 -{number = 2, name = (``null``)}
2015-07-28 17:50:16.586 test[17527:4095666] 第3次 -{number = 4, name = (``null``)}
2015-07-28 17:50:16.586 test[17527:4095467] 第4次 -{number = 1, name = main}
创建队列
看过上面的内容就知道,我们可以调用一个
- 主线程
//OBJECTIVE-C
NSOperationQueue *queue = [NSOperationQueue mainQueue];
//SWIFT
let queue = NSOperationQueue.mainQueue()
- 其他队列
因为主队列比较特殊,所以会单独有一个类方法来获得主队列。那么通过初始化产生的队列就是其他队列了,因为只有这两种队列,除了主队列,其他队列就不需要名字了。注意:其他队列的任务会在其他线程并行执行。
//1.创建一个其他队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
//2.创建NSBlockOperation对象
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"%@", [NSThread currentThread]);
}];
//3.添加多个Block
for (NSInteger i = 0; i < 5; i++) {
[operation addExecutionBlock:^{
NSLog(@"第%ld次:%@", i, [NSThread currentThread]);
}];
}
//4.队列添加任务
[queue addOperation:operation];
任务依赖
//1.任务一:下载图片
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"下载图片 - %@", [NSThread currentThread]);
[NSThread sleepForTimeInterval:1.0];
}];
//2.任务二:打水印
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"打水印 - %@", [NSThread currentThread]);
[NSThread sleepForTimeInterval:1.0];
}];
//3.任务三:上传图片
NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"上传图片 - %@", [NSThread currentThread]);
[NSThread sleepForTimeInterval:1.0];
}];
//4.设置依赖
[operation2 addDependency:operation1]; //任务二依赖任务一
[operation3 addDependency:operation2]; //任务三依赖任务二
//5.创建队列并加入任务
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperations:@[operation3, operation2, operation1] waitUntilFinished:NO];