block深刻浅出

typedef void (^Callback)(id result);
- (void)viewDidLoad {
[self callbackDosomething:^(id result) {
NSLog(@"%@",result);
}];

}

- (void)callbackDosomething:(Callback)callback{
callback = [self callbackReDosomething:callback];
}

- (Callback)callbackReDosomething:(Callback)callback{
if (callback) {
callback(@"dosomething");
}
return callback;
}
此处的callback就是用来传递的,在另外一个方法里面才callback回调

block是OC对闭包实现的一个对象,为何说block是对象了,由于在block的数据结构中存在isa指针objective-c

一、block分为三种:NSConcreteGlobalBlock、NSConcreteStackBlock、NSConcreteMallocBlock。数据结构

第一种block是全局block,若是一个block没有引入外部变量,那么这个block就是全局block,全局block在编译时期就已经肯定大小了,如同宏同样;
第二种block是栈block,当引入了外部变量时,这种block就是栈block了,NSConcreteStackBlock内部会有一个结构体__main_block_impl_0,这个结构体会保存外部变量,使其体积变大。而这就致使了NSConcreteStackBlock并不像宏同样,而是一个动态的对象。而它因为没有被持有,因此在它的内部,它也不会持有其外部引用的对象。(注意,栈block是不会持有外部变量的)
第三种block是堆block,堆block就是一个block被copy到堆上,堆block会持有外部引用对象,因此会致使可能的对象延迟释放,或者循环引用的问题。(在MRC下,局部变量若是没有用_block,在block中会对其进行copy操做,而用了_block则只会引用其地址,这也就是为何改变局部变量须要用_block修饰了)闭包

注意:在MRC和ARC下block的区别
将block做为实例的属性变量时,MRC下须要手动copy到堆中,也就是栈block–>堆block(若是不copy就是栈block,栈block不会持有对象),而在ARC中属性赋值默认是strong,到了block天然就变成了copy,因此在ARC下默认是堆block。指针

block 的生命周期:
(特别注意:堆block会持有对象,这样就致使,若是堆block不释放的话,其持有的对象也不会释放,这样就会致使循环引用或者延迟释放,因此通常的作法是_weak(ARC)或_block(MRC))code

宏:
·#define weak(obj) __weak typeof(obj) weak##obj = obj对象

相关文章
相关标签/搜索