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對象

相關文章
相關標籤/搜索