美文网首页
iOS delegate线程引发的思考

iOS delegate线程引发的思考

作者: 鹏雨燕 | 来源:发表于2020-05-14 17:57 被阅读0次

    在代理模式中,当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更新了

    相关文章

      网友评论

          本文标题:iOS delegate线程引发的思考

          本文链接:https://www.haomeiwen.com/subject/gluiyctx.html