在代理模式中,当obj1通过delegate委托obj2执行某个操作时,我们会对委托执行回调的线程感兴趣。
先定义一个viewcontroller作为obj1,在其中执行循环委托TestViewController去执行委托
#import "ViewController.h"
#import "TestViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[testObject shareInstance];
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
[btn setBackgroundColor:[UIColor redColor]];
[btn addTarget:self action:@selector(pushNavigate) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
[self touchEvent];
// Do any additional setup after loading the view.
}
-(void)pushNavigate{
TestViewController *vc = [[TestViewController alloc] init];
vc.view.backgroundColor = [UIColor greenColor];
[self.navigationController pushViewController:vc animated:YES];
}
-(void)touchEvent{
dispatch_queue_t q = dispatch_queue_create("threadTest", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(q, ^{
if([[testObject shareInstance].testDelegate respondsToSelector:@selector(delegatePrint:)]) {
NSLog(@"in loop1%@",[NSThread currentThread]);
[[testObject shareInstance].testDelegate delegatePrint:@"test"];
}
});
[self performSelector:@selector(touchEvent) withObject:nil afterDelay:1];
}
@end
新建一个委托中间人,一个单例
static testObject *share;
@implementation testObject
+(instancetype)shareInstance;
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
share = [[super alloc] init];
});
return share;
}
@end
再看下被委托人obj2 的内容,很简单的一个委托方法
#import "TestViewController.h"
@interface TestViewController ()
@end
@implementation TestViewController
- (void)viewDidLoad {
[super viewDidLoad];
[testObject shareInstance].testDelegate = self;
// Do any additional setup after loading the view.
}
-(void)delegatePrint:(NSString *)value;
{
UILabel *lable = [self.view viewWithTag:99];
lable.text = value;
NSLog(@"in loop2%@",[NSThread currentThread]);
}
@end
不管obj1在哪个线程中对代理人派发委托事件,obj2委托执行的线程和派发时线程一致
2019-09-11 11:09:23.706339+0800 xcodeTest[33110:499973] in loop1<NSThread: 0x600003b16700>{number = 4, name = (null)}
2019-09-11 11:09:23.706691+0800 xcodeTest[33110:499973] in loop2<NSThread: 0x600003b16700>{number = 4, name = (null)}
所以啊,这里有个地方要注意,在使用代理的时候,代理派发的线程不确定时,有些UI主线程的修改,最好就用block包起来
dispatch_async(dispatch_get_main_queue(), ^{
UILabel *lable = [self.view viewWithTag:99];
lable.text = value;
});
可以看到obj2的lable更新了
网友评论