0
点赞
收藏
分享

微信扫一扫

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 我的作品

欢迎体验我的作品之一:​​小编辑器​​​ 在线编辑器
​App Store​​ 搜索即可~


举报

相关推荐

0 条评论