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 搜索即可~










