一.使用NSPort进行线程间的通讯(端口和套接字来实现线程间通讯)
NSPort对象必须添加到要接收消息的线程的Runloop中NSPortDelegate协议的-handlePortMessage:方法来获取消息内容 代码中首先将self.mainPort添加到主线程的Runloop中,然后起新线程下载头像,下载完成后通过mainPort发送消息,此时并没有手动切换线程,但是controller中的回调却是在主线程中的,如此便完成了线程间的通讯。
self.mainPort = [[NSMachPort alloc]init];
// self.mainPort.delegate = self;
NSMutableArray *components = @[data].mutableCopy;
[self.port sendBeforeDate:[NSDate date] msgid:1 components:components from:self.downloaderPort reserved:0];
//代理方法
-(void)handlePortMessage:(NSPortMessage *)message{
NSLog(@"handlePortMessage: %@", [NSThread currentThread]);
NSArray *array = [(id)message valueForKey:@"components"];
NSData *data = array[0];
UIImage *avatar = [UIImage imageWithData:data];
imgv.image = avatar;
NSData *responseMsg = [@"附带的信息" dataUsingEncoding:NSUTF8StringEncoding];
NSMutableArray *components = @[responseMsg].mutableCopy;
NSPort *remotePort = [(id)message valueForKey:@"remotePort"];
// downloader线程已销毁,因此要给remotePort发消息,就得把它添加到存活的runloop中
[[NSRunLoop currentRunLoop] addPort:remotePort forMode:NSDefaultRunLoopMode];
[remotePort sendBeforeDate:[NSDate date] msgid:2 components:components from:self.mainPort reserved:0];
}
三:NSCondition
- // 生产者-消费者模式
-
- // 线程1
- // 删除数组中的元素
- - (void)__remove
- {
- [self.condition lock];
- if (self.data.count == 0) {
- // 等待
- [self.condition wait];
- }
- [self.data removeLastObject];
- [self.condition unlock];
- }
-
- // 线程2
- // 往数组中添加元素
- - (void)__add
- {
- [self.condition lock];
- [self.data addObject:@"Test"];
- // 信号
- [self.condition signal];
- // 广播
- //[self.condition broadcast];
- [self.condition unlock];
- }
二:NSConditionLock 条件锁,是对NSCondition的进一步封装
当使用条件锁使一个线程等待(wait)时,该线程会被阻塞并进入休眠状态,在另一个线程中对同一个条件锁发送信号(single),则等待中的线程会被唤醒继续执行任务
- //构建条件锁,条件值为1
- NSConditionLock *lock = [[NSConditionLock alloc]initWithCondition:1];
-
- dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
- //线程1 传入9,与条件值不相等,无法正确进行加锁操作,会阻塞线程
- [lock lockWhenCondition:9];
- NSLog(@"11111");
- sleep(1);
- [lock unlock];
- });
-
-
- dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
- sleep(1);
- //传入1,如果与条件的值相等,返回YES;如果不相等则返回NO; 不会阻塞当前线程
- if ([lock tryLockWhenCondition:1]) {
- NSLog(@"22222");
- NSLog(@"2加锁");
- //解锁,并把条件值修改为9
- [lock unlockWithCondition:9];
- // [lock unlock];
-
- }else{
- NSLog(@"2加锁失败");
- }
- });