1.__block简介
__block可以用于解决block内部无法修改auto变量值的问题, __block不能修饰全局变量、静态变量(static),编译器会将__block变量(不管是基本数据类型还是对象类型)包装成一个对象。
- 代码
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "YMPerson.h"
typedef void(^YMBlock)(void);
int main(int argc, char * argv[]) {
@autoreleasepool {
// 基本数据类型
__block int a = 10;
YMBlock block = ^{
a = 20;
};
block();
NSLog(@"a == %d",a);
// 对象类型
YMPerson *person = [[YMPerson alloc] init];
person.age = 10;
__block YMPerson *blockPerson = person;
YMBlock block1 = ^{
// 这不是修改person对象 是使用person对象 此步骤不使用__block修饰也可
person.age = 20;
// 修改person对象,必须用__block修饰
blockPerson = [[YMPerson alloc] init];
blockPerson.age = 100;
};
block1();
NSLog(@"person.age == %d",person.age);
NSLog(@"blockPerson.age == %d",blockPerson.age);
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
-
运行结果
block修饰
2.__block修饰变量的内存管理
1.当block在栈上时,并不会对__block变量产生强引用。
2.当__block变量被copy到堆时,会调用__block变量内部的copy函数,copy函数内部会调用_Block_object_assign函数,_Block_object_assign函数会根据所指向对象的修饰(__strong、__weak、__unsafe_unretained)做出相应的操作,形成强引用(retain)或者弱引用(注意:这里仅限于ARC时会retain,MRC时不会retain)。
3. 如果__block变量从堆上移除,会调用__block变量内部的dispose函数,dispose函数内部会调用_Block_object_dispose函数,_Block_object_dispose函数会自动释放指向的对象(release)。
3.__block __weak同时修饰
block内部不会对对象进行强引用
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "YMPerson.h"
typedef void(^YMBlock)(void);
int main(int argc, char * argv[]) {
@autoreleasepool {
YMBlock block;
{
YMPerson *person = [[YMPerson alloc] init];
person.age = 10;
__block __weak YMPerson *blockPerson = person;
block = ^{
blockPerson.age = 100;
};
}
block();
NSLog(@"---");
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
-
运行结果
__block __weak 同时修饰
网友评论