天天看點

iOS 關于 Block 你不知道的新用法

0x00 UIControl

都是以 ​

​block​

​ 為 target,​

​action​

​ 為 @selector(invoke)

以 ​

​UIButton​

​ 為例:

dispatch_block_t block = ^{
        NSLog(@"點選按鈕 666");
    };
    
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectMake(0, 0, 100, 62);
    button.backgroundColor = [UIColor lightGrayColor];
    button.titleLabel.font = [UIFont systemFontOfSize:16];
    [button setTitle:@"666" forState:0];
    [button setTitleColor:[UIColor blackColor] forState:0];
    [button addTarget:block action:@selector(invoke) forControlEvents:1<<6];
    [self.view addSubview:button];      

如果你這樣寫 ​

​block​

​:

__weak typeof(self) ws = self;
    dispatch_block_t block = ^{
        NSLog(@"點選按鈕 666");
        [ws.navigationController popViewControllerAnimated:YES];
    };      

​block​

​​ 就不會被調用了

原因:​​

​後面再說​

​~

話說:

直接設定 ​​

​target​

​ 為 self,為啥還要中間加個 ​

​Block​

​ 呢?😂😂

0x01 UIGestureRecognizer

以 ​

​UITapGestureRecognizer​

​ 為例:

dispatch_block_t block = ^{
        NSLog(@"點選圖檔 888");
    };
    
    UIImageView *imageView = [[UIImageView alloc] init];
    imageView.frame = CGRectMake(CGRectGetMidX(button.frame)-50, CGRectGetMaxY(button.frame)+10, 100, 60);
    imageView.image = [UIImage imageNamed:@"01"];
    imageView.userInteractionEnabled = YES;
    [imageView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:block action:@selector(invoke)]];
    [self.view addSubview:imageView];      

0x02 NSTimer

dispatch_block_t block = ^ {
        NSLog(@"定時器 666");
    };
    
    [NSTimer scheduledTimerWithTimeInterval:1 target:block selector:@selector(invoke) userInfo:@{@"name":@"張三", @"age":@"18"} repeats:YES];      

0x04 解答

為什麼 ​

​block​

​​ 就不會被調用了?

這個涉及到 ​​

​block​

​ 在記憶體中的 存儲 位置

當一個 ​

​block​

​ 内部 沒有通路 外部的局部變量時

它是一個 ​​

​global​

​​ 類型的 ​

​block​

​​,存放在記憶體中的 ​

​data​

​ 區,相當于是誰都可以通路

當一個 ​

​block​

​ 内部 通路了 外部的局部變量時

它是一個 ​​

​stack​

​​ 類型的 ​

​block​

​​,存放在記憶體中的 ​

​棧​

​​ 區,它的生命隻存在于目前方法内部

方法調用完後,它就已經 ​​

​芭比 Q 了​

​​, 相當于是 ​

​來過,再見​

​​ 是以,當點選按鈕時,​

​block​

​ 都已經沒了,是以沒有日志輸出

0x05 我的作品