iOS delegate线程引发的思考

在代理模式中,当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{number = 4, name = (null)}
2019-09-11 11:09:23.706691+0800 xcodeTest[33110:499973] in loop2{number = 4, name = (null)}

所以啊,这里有个地方要注意,在使用代理的时候,代理派发的线程不确定时,有些UI主线程的修改,最好就用block包起来

    dispatch_async(dispatch_get_main_queue(), ^{
        UILabel *lable = [self.view viewWithTag:99];
        lable.text = value;
    });

可以看到obj2的lable更新了

你可能感兴趣的:(iOS delegate线程引发的思考)