此类的例子很多博客都有,只是解释的都很模糊,看了也还是不明白
第一题: test会打印什么?因为啥?
typedef void(^TestBlock)(void);
NSString *test = @"test1111";
NSLog(@"内存地址1:%p 指针地址1: %x",test,&test);
TestBlock b2 = ^(void){
NSLog(@"%@",test);
NSLog(@"内存地址2:%p 指针地址2: %x",test,&test);
};
test = @"test2222";
b2();
NSLog(@"内存地址3:%p 指针地址3: %x",test,&test);
- 答案是test1111
原因:
/*
2019-03-07 15:36:02.437971+0800 OCVoicePro[65484:1357190] 内存地址1:0x10b654448 指针地址1: e50af2b8
2019-03-07 15:36:02.438218+0800 OCVoicePro[65484:1357190] test1111
2019-03-07 15:36:02.438354+0800 OCVoicePro[65484:1357190] 内存地址2:0x10b654448 指针地址1: 294c0
2019-03-07 15:36:02.438471+0800 OCVoicePro[65484:1357190] 内存地址3:0x10b6544c8 指针地址3: e50af2b8
*/
c++block代码:
static void __QQViewController__viewDidLoad_block_func_0(struct __QQViewController__viewDidLoad_block_impl_0 *__cself) {
NSString *test = __cself->test; // bound by copy
//注释:拷贝了新的test指针
NSLog((NSString *)&__NSConstantStringImpl__var_folders_xl_5h4m37_n34b2xnc4gxq3z8r80000gn_T_QQViewController_2ba859_mi_1,test);
}
-Block会对外部的变量进行一次"临时“的”拷贝“.产生一个新的指针,对象地址不变
第二题: label会显示什么字样?
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 300, 300, 40)];
NSLog(@"内存地址1:%p 指针地址1: %x",label,&label);
label.text = @"block作用域外赋值++++";
void (^backValue)(NSString *) = ^(NSString *str) {
label.text = str;
NSLog(@"内存地址2:%p 指针地址2: %x",label,&label);
};
backValue(@"block作用域内赋值------");
NSLog(@"内存地址3:%p 指针地址3: %x",label,&label);
[self.view addSubview:label];
- 答案是block作用域内赋值------
原因:
/*
2019-03-07 15:26:52.991643+0800 OCVoicePro[65387:1352714] 内存地址1:0x7fb253c1a740 指针地址1: ee08d280
2019-03-07 15:27:25.625023+0800 OCVoicePro[65387:1352714] 内存地址2:0x7fb253c1a740 指针地址2: 2bca2a0
2019-03-07 15:27:52.486911+0800 OCVoicePro[65387:1352714] 内存地址3:0x7fb253c1a740 指针地址3: ee08d280
*/
c++block代码:
static void __TTViewController__viewDidLoad_block_func_0(struct __TTViewController__viewDidLoad_block_impl_0 *__cself, NSString *str) {
UILabel *label = __cself->label; // bound by copy
//注释:拷贝了新的label指针
((void (*)(id, SEL, NSString * _Nullable))(void *)objc_msgSend)((id)label, sel_registerName("setText:"), (NSString *)str);
}
- label的指针同样被拷贝,label.text = str;的赋值是通过runtime发送了一个setText的消息对label的text属性进行改变.