iOS底层学习-day-9
前言-OC语法篇
我是一名iOS开发者, iOS底层 菜鸟的进阶之路30天。
问题
block的属性修饰词为什么是copy?使用block有哪些使用注意?
- block一旦没有进行copy操作,就不会在堆上
- 使用注意:循环引用问题
block在修改NSMutableArray,需不需要添加__block?
- 不需要。修改内容也是对数组的使用,只有对对象赋值的时候才需要__block。
block的持有问题
//栈空间的block是不可以对对象强引用的,堆空间的block是可以持有对象
Block block;
{
Person *person = [[Person alloc] init];
person.age = 10;
block = ^{
NSLog(@"---------%d", person.age);
};
}
NSLog(@"------");
Block block;
{
Person *person = [[Person alloc] init];
person.age = 10;
//如果是这样就,这个block就只是栈上的,就不会对外部变量进行强引用(ARC环境)
^{
NSLog(@"---------%d", person.age);
};
}
NSLog(@"------");
-
当block内部访问了对象类型的auto变量时
- 如果block是在栈上,将不会对auto变量产生强引用
-
如果block被拷贝到堆上
- 会调用block内部的copy函数
- copy函数内部会调用_Block_object_assign函数
- _Block_object_assign函数会根据auto变量的修饰符(__strong、__weak__unsafe_unretained)做出相应的操作,形成强引用(retain)或者弱引用
-
如果block从堆上移除
- 会调用block内部的dispose函数
- dispose函数内部会调用_Block_object_dispose函数
_Block_object_dispose函数会自动释放引用的auto变量(release)
p的强引用什么时候被释放问题
- 全局变量没有捕获,因为全局变量直接可以访问
- 这样会,先强引用里面的代码,所以,weakP 1秒也是之后被释放,p 3秒之后被释放
Person *p = [[Person alloc] init];
__weak Person *weakP = p;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"1-------%@", weakP);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"2-------%@", p);
});
});
- p 1秒之后被释放,weakP 一下就被释放
Person *p = [[Person alloc] init];
__weak Person *weakP = p;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"1-------%@", p);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"2-------%@", weakP);
});
});
在block中修改变量
- 不可以修改,因为在block里相当于拿到block的行参
int age = 10;
Block block1 = ^{
age = 30;
NSLog(@"age is %d", age);
};
- 这样就可以改了,因为是直接改指针指向的内存,全局变量也可以改
static int age = 10;//会永久在内存中
Block block2 = ^{
age = 30;
NSLog(@"age is %d", age);
};
- 编译器会将__block变量包装成一个对象
//__blcok只能修改auto变量
//还是一个auto变量
__block int age = 10;
Block block3 = ^{
age = 20;
NSLog(@"age is %d", age);
};
- __block本质