2. Blocks
2018-04-02 本文已影响20人
清無
image.png
image.png
image.png image.png image.png image.png image.png
image.png
image.png image.png image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png image.png image.png image.png image.png
image.png
image.png image.png image.png
image.png
image.png
image.png
_NSConcreteStackBlock; //栈区
_NSConcreteGlobalBlock; //.data数据区
_NSConcreteMallocBlock; //堆区
_Block_object_assign //retain
_Block_object_dispose //release
image.png
image.png
将栈区的block复制到堆区,用_Block_copy方法,注册到autoreleasepool中,然后返回该对象
tmp = _Block_copy(tmp);
return objc_autoreleaseReturnValue(tmp);
image.png
image.png
image.png
// id为objc_object类型的结构体指针
typedef struct objc_object{
Class *isa;
} *id;
// Class为objc_class类型的结构体指针,与id类型结构一致
typedef struct objc_class{
Class isa;
} *Class;
struct Test{
Class isa;
int a;
int b;
};
struct class_t{
struct class_t *isa;
struct class_t *superclass;
Cache cache;
IMP *vtable;
uintptr_t data_NEVER_USE;
};
void (^block)(id obj);
{
id array = [NSMutableArray new];
block = [ ^(id obj){
[array addObject:obj];
NSLog(@"array: %@",array);
} copy ];
}
block([NSObject new]);
block([NSObject new]);
block([NSObject new]);
循环引用
typedef void(^Block)(void);
@interface Test: NSObject
{
Block _block;
}
@end
@implementation Test
-(instancetype)init{
self = [super init];
// 改为弱引用方式即可避免
id __weak weakSelf = self;
_block = ^{
NSLog(@"self = %@", self); //_block引用self,self拥有_block
NSLog(@"_var = %@", _var); //也会引起循环引用,相当于间接截获了self
//使用_var等同于self->_var
// 这样即可避免
id __weak obj = _val;
_block = ^{
NSLog(@"_val = %@", obj);
};
};
return self;
}
-(void)dealloc{
NSLog(@"dealloc");
}
@end
image.png
image.png
id array = [NSMutableArray new];
void (^add)(void) = ^{
id obj = [NSObject new];
[array addObject:obj];
};
add();
NSLog(@"array: %@",array);
typedef int (^SumBlock)(int a, int b);
__block int result = 0;
SumBlock sum = ^(int a, int b){
result = a + b;
return result;
};
sum(1,2);
NSLog(@"result: %d", result);
typedef int (^SumBlock)(int a, int b);
SumBlock sum = ^(int a, int b){
return a + b;
};
NSLog(@"sum: %d", sum(1, 1));
void (^block)(int a);
block = ^(int a){
NSLog(@"block var: %d",a);
};
block(10);
^{
NSLog(@"block");
}();
^(int a){
NSLog(@"%d", a);
}(10);
int sum = ^(int a, int b){ return a + b; }(5, 1);
NSLog(@"sum: %d", sum);