大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE稳定放心使用
什么叫做线程间通信
- 在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信
线程间通信的体现
- 1个线程传递数据给另1个线程
- 在1个线程中执行完特定任务后,转到另1个线程继续执行任务
线程间通信常用方法
1. NSThread :一个线程传递数据给另一个线程
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait;
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait NS_AVAILABLE(10_5, 2_0);
//具体用法如下:
//点击屏幕开始执行下载方法
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self performSelectorInBackground:@selector(download) withObject:nil];
}
//下载图片
- (void)download
{
// 1.图片地址
NSString *urlStr = @"http://d.jpg";
NSURL *url = [NSURL URLWithString:urlStr];
// 2.根据地址下载图片的二进制数据
NSData *data = [NSData dataWithContentsOfURL:url];
// 3.设置图片
UIImage *image = [UIImage imageWithData:data];
// 4.回到主线程,刷新UI界面(为了线程安全)
[self performSelectorOnMainThread:@selector(downloadFinished:) withObject:image waitUntilDone:NO];
// [self performSelector:@selector(downloadFinished:) onThread:[NSThread mainThread] withObject:image waitUntilDone:YES];
}
- (void)downloadFinished:(UIImage *)image
{
self.imageView.image = image;
NSLog(@"downloadFinished---%@", [NSThread currentThread]);
}
2. GCD :一个线程传递数据给另一个线程
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"donwload---%@", [NSThread currentThread]);
// 1.子线程下载图片
NSURL *url = [NSURL URLWithString:@"http://d.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
// 2.回到主线程设置图片
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"setting---%@ %@", [NSThread currentThread], image);
[self.button setImage:image forState:UIControlStateNormal];
});
});
}
3. NSMachPort
NSPort有3个子类,NSSocketPort、NSMessagePort、NSMachPort,但在iOS下只有NSMachPort可用。
#define kMsg1 100
#define kMsg2 101
- (void)viewDidLoad {
[super viewDidLoad];
//1. 创建主线程的port
// 子线程通过此端口发送消息给主线程
NSPort *myPort = [NSMachPort port];
//2. 设置port的代理回调对象
myPort.delegate = self;
//3. 把port加入runloop,接收port消息
[[NSRunLoop currentRunLoop] addPort:myPort forMode:NSDefaultRunLoopMode];
//4. 启动次线程,并传入主线程的port
MyWorkerClass *work = [[MyWorkerClass alloc] init];
[NSThread detachNewThreadSelector:@selector(launchThreadWithPort:)
toTarget:work
withObject:myPort];
}
- (void)handlePortMessage:(NSMessagePort*)message{
NSLog(@"接到子线程传递的消息!%@",message);
//1. 消息id
NSUInteger msgId = [[message valueForKeyPath:@"msgid"] integerValue];
//2. 当前主线程的port
NSPort *localPort = [message valueForKeyPath:@"localPort"];
//3. 接收到消息的port(来自其他线程)
NSPort *remotePort = [message valueForKeyPath:@"remotePort"];
if (msgId == kMsg1)
{
//向子线的port发送消息
[remotePort sendBeforeDate:[NSDate date]
msgid:kMsg2
components:nil
from:localPort
reserved:0];
}else if (msgId == kMsg2){
NSLog(@"操作2....\n");
}
}
//MyWorkerClass类
#import "MyWorkerClass.h"
@interface MyWorkerClass() <NSMachPortDelegate> {
NSPort *remotePort;
NSPort *myPort;
}
@end
#define kMsg1 100
#define kMsg2 101
@implementation MyWorkerClass
- (void)launchThreadWithPort:(NSPort *)port {
@autoreleasepool {
//1. 保存主线程传入的port
remotePort = port;
//2. 设置子线程名字
[[NSThread currentThread] setName:@"MyWorkerClassThread"];
//3. 开启runloop
[[NSRunLoop currentRunLoop] run];
//4. 创建自己port
myPort = [NSPort port];
//5.
myPort.delegate = self;
//6. 将自己的port添加到runloop
//作用1、防止runloop执行完毕之后推出
//作用2、接收主线程发送过来的port消息
[[NSRunLoop currentRunLoop] addPort:myPort forMode:NSDefaultRunLoopMode];
//7. 完成向主线程port发送消息
[self sendPortMessage];
}
}
/**
* 完成向主线程发送port消息
*/
- (void)sendPortMessage {
NSMutableArray *array =[[NSMutableArray alloc]initWithArray:@[@"1",@"2"]];
//发送消息到主线程,操作1
[remotePort sendBeforeDate:[NSDate date]
msgid:kMsg1
components:array
from:myPort
reserved:0];
}
#pragma mark - NSPortDelegate
/**
* 接收到主线程port消息
*/
- (void)handlePortMessage:(NSPortMessage *)message
{
NSLog(@"接收到父线程的消息...\n");
}
@end
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/185177.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...