1.子线程中代理回调
**子线程中默认没有Runloop,所以delegate默认无法在子线程中回调**
**子线程异步请求 创建runloop 在runloop中添加代理 设置nsmachport 进行线程通讯,调用方法 执行子线程,相关代理执行,逆地理编码成功后 移除通讯 **
- (void)location{
dispatch_queue_t deleQue = dispatch_queue_create("haha", DISPATCH_QUEUE_SERIAL);
dispatch_async(deleQue, ^{
_runloop = [NSRunLoop currentRunLoop];
_port = [NSMachPort port];
[_runloop addPort:_port forMode:NSDefaultRunLoopMode];
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
[self startLocation];
[_runloop run];
});
}
- (void)startLocation
{
if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestWhenInUseAuthorization];
}
[self.locationManager startUpdatingLocation];
NSLog(@"开始定位");
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *location = [locations lastObject];
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
//逆地理编码
[geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark> * _Nullable placemarks, NSError * _Nullable error) {
if (error || [placemarks count] == 0)
{
NSLog(@"逆地理编码错误,error = %@", error);
return;
}
NSDictionary *addressDic = [[placemarks objectAtIndex:0] addressDictionary];
[_runloop removePort:_port forMode:NSDefaultRunLoopMode];
if (_locationSuccess) {
_locationSuccess(addressDic);
}
NSLog(@"dic = %@",addressDic);
}];
[manager stopUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error
{
if (error.code == kCLErrorDenied) {
}
NSLog(@"定位失败");
}
2.线程依赖
1) //NSOperationQueue 线程之前添加依赖操作
-(void)dependency{
/**
假设有A、B、C三个操作,要求:
1. 3个操作都异步执行
2. 操作C依赖于操作B
3. 操作B依赖于操作A
*/
//创建一个队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
//可开辟线程的最大数量
queue.maxConcurrentOperationCount = 3;
//创建三个任务
NSBlockOperation *operationA = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"A任务当前线程为:%@", [NSThread currentThread]);
}];
NSBlockOperation *operationB = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"B任务当前线程为:%@", [NSThread currentThread]);
}];
NSBlockOperation *operationC = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"C任务当前线程为:%@", [NSThread currentThread]);
}];
//设置三个任务相互依赖
// operationB 任务依赖于 operationA
[operationB addDependency:operationA];
// operationC 任务依赖于 operationB
[operationC addDependency:operationB];
//添加操作到队列中(自动异步执行任务,并发)
[queue addOperation:operationA];
[queue addOperation:operationB];
[queue addOperation:operationC];
[NSOpeationQueue mainQueue] addOperation ^{
}];
}
** 2)GCD**
当dispatch_group_async的block里面执行的是异步任务,如果还是使用上面的方法你会发现异步任务还没跑完就已经进入到了dispatch_group_notify方法里面了,这时用到dispatch_group_enter和dispatch_group_leave就可以解决这个问题:
#pragma mark - 下载基础数据
- (void)downloadBaseData
{
// 全局变量group
group = dispatch_group_create();
// 并行队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 进入组(进入组和离开组必须成对出现, 否则会造成死锁)
dispatch_group_enter(group);
dispatch_group_async(group, queue, ^{
// 执行异步任务1
[self fetchBaseData];
});
// 进入组
dispatch_group_enter(group);
dispatch_group_async(group, queue, ^{
// 执行异步任务2
[self fetchInspectorBaseData];
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
[SVProgressHUD dismiss];
ILog(@"全部基础数据下载完毕!");
[[AppDelegate sharedDelegate] showMainView];
});
3.目标队列相关
+(void)testTargetQueue {
dispatch_queue_t targetQueue = dispatch_queue_create("test.target.queue", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t queue1 = dispatch_queue_create("test.1", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t queue2 = dispatch_queue_create("test.2", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t queue3 = dispatch_queue_create("test.3", DISPATCH_QUEUE_SERIAL);
dispatch_set_target_queue(queue1, targetQueue);
dispatch_set_target_queue(queue2, targetQueue);
dispatch_set_target_queue(queue3, targetQueue);
dispatch_async(queue1, ^{
NSLog(@"1 in");
[NSThread sleepForTimeInterval:3.f];
NSLog(@"1 out");
});
dispatch_async(queue2, ^{
NSLog(@"2 in");
[NSThread sleepForTimeInterval:2.f];
NSLog(@"2 out");
});
dispatch_async(queue3, ^{
NSLog(@"3 in");
[NSThread sleepForTimeInterval:1.f];
NSLog(@"3 out");
});
}
输出
1 in
1 out
2 in
2 out
3 in
3 out
网友评论