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